Skip to content

Commit 35248e7

Browse files
committed
fix(renderer): handle error rendering
Required adding support for replacing messages... fortunately, that was straightforward to add. Also disable session.error reporting for now (except when debug is enabled) as those errors seem duplicative?
1 parent 0f0e9fb commit 35248e7

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-16
lines changed

lua/opencode/ui/formatter.lua

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,8 @@ function M._format_error(output, message)
220220
end
221221

222222
---@param message OpencodeMessage
223-
---@param msg_idx number Message index in the session
224223
---@return Output
225-
function M.format_message_header(message, msg_idx)
224+
function M.format_message_header(message)
226225
local output = Output.new()
227226

228227
output:add_lines(M.separator)
@@ -236,7 +235,6 @@ function M.format_message_header(message, msg_idx)
236235
local debug_text = config.debug and ' [' .. message.info.id .. ']' or ''
237236

238237
output:add_empty_line()
239-
output:add_metadata({ msg_idx = msg_idx, part_idx = 1, role = role, type = 'header' })
240238

241239
local display_name
242240
if role == 'assistant' then
@@ -246,7 +244,7 @@ function M.format_message_header(message, msg_idx)
246244
else
247245
-- For the most recent assistant message, show current_mode if mode is missing
248246
-- This handles new messages that haven't been stamped yet
249-
local is_last_message = msg_idx == #state.messages
247+
local is_last_message = #state.messages == 0 or message.info.id == state.messages[#state.messages].info.id
250248
if is_last_message and state.current_mode and state.current_mode ~= '' then
251249
display_name = state.current_mode:upper()
252250
else
@@ -270,6 +268,14 @@ function M.format_message_header(message, msg_idx)
270268
priority = 10,
271269
})
272270

271+
if role == 'assistant' and message.info.error and message.info.error ~= '' then
272+
local error = message.info.error
273+
local error_messgage = error.data and error.data.message or vim.inspect(error)
274+
275+
output:add_line('')
276+
M._format_callout(output, 'ERROR', error_messgage)
277+
end
278+
273279
output:add_line('')
274280
return output
275281
end

lua/opencode/ui/renderer.lua

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,6 @@ function M._render_full_session_data(session_data)
137137
for j, part in ipairs(msg.parts or {}) do
138138
M.on_part_updated({ part = part })
139139
end
140-
141-
-- FIXME: not sure how this error rendering code works when streaming
142-
-- if msg.info.error and msg.info.error ~= '' then
143-
-- vim.notify('calling _format_error')
144-
-- M._format_error(output, msg.info)
145-
-- end
146140
end
147141

148142
M._scroll_to_bottom()
@@ -316,6 +310,37 @@ function M._remove_message_from_buffer(message_id)
316310
M._render_state:remove_message(message_id)
317311
end
318312

313+
---Replace existing message header in buffer
314+
---@param message_id string Message ID
315+
---@param formatted_data Output Formatted header as Output object
316+
---@return boolean Success status
317+
function M._replace_message_in_buffer(message_id, formatted_data)
318+
vim.notify('replacing message in buffer')
319+
local cached = M._render_state:get_message(message_id)
320+
if not cached or not cached.line_start or not cached.line_end then
321+
return false
322+
end
323+
324+
local new_lines = formatted_data.lines
325+
local new_line_count = #new_lines
326+
327+
output_window.clear_extmarks(cached.line_start, cached.line_end + 1)
328+
output_window.set_lines(new_lines, cached.line_start, cached.line_end + 1)
329+
output_window.set_extmarks(formatted_data.extmarks, cached.line_start)
330+
331+
local old_line_end = cached.line_end
332+
local new_line_end = cached.line_start + new_line_count - 1
333+
334+
M._render_state:set_message(message_id, cached.message, cached.line_start, new_line_end)
335+
336+
local delta = new_line_end - old_line_end
337+
if delta ~= 0 then
338+
M._render_state:shift_all(old_line_end + 1, delta)
339+
end
340+
341+
return true
342+
end
343+
319344
---Event handler for message.updated events
320345
---Creates new message or updates existing message info
321346
---@param message {info: MessageInfo} Event properties
@@ -334,11 +359,20 @@ function M.on_message_updated(message)
334359
local found_msg = rendered_message and rendered_message.message
335360

336361
if found_msg then
362+
-- see if an error was added (or removed). have to check before we set
363+
-- found_msg.info = message.info below
364+
local rerender_message = not vim.deep_equal(found_msg.info.error, message.info.error)
365+
337366
found_msg.info = message.info
367+
368+
if rerender_message then
369+
local header_data = formatter.format_message_header(found_msg)
370+
M._replace_message_in_buffer(message.info.id, header_data)
371+
end
338372
else
339373
table.insert(state.messages, message)
340374

341-
local header_data = formatter.format_message_header(message, #state.messages)
375+
local header_data = formatter.format_message_header(message)
342376
local range = M._write_formatted_data(header_data)
343377

344378
if range then
@@ -508,13 +542,19 @@ function M.on_session_error(properties)
508542
return
509543
end
510544

511-
local error_data = properties.error
512-
local error_message = error_data.data and error_data.data.message or vim.inspect(error_data)
545+
-- NOTE: we're handling message errors so session errors seem duplicative
513546

514-
local formatted = formatter.format_error_callout(error_message)
547+
if config.debug.enabled then
548+
vim.notify('Session error: ' .. vim.inspect(properties.error))
549+
end
515550

516-
M._write_formatted_data(formatted)
517-
M._scroll_to_bottom()
551+
-- local error_data = properties.error
552+
-- local error_message = error_data.data and error_data.data.message or vim.inspect(error_data)
553+
--
554+
-- local formatted = formatter.format_error_callout(error_message)
555+
--
556+
-- M._write_formatted_data(formatted)
557+
-- M._scroll_to_bottom()
518558
end
519559

520560
---Event handler for permission.updated events

0 commit comments

Comments
 (0)