nvim-neotest / neotest

An extensible framework for interacting with tests within NeoVim.
MIT License
2.12k stars 105 forks source link

fix: avoid arithmetic error (subtracting 1 from nil) #396

Closed fredrikaverpil closed 2 months ago

fredrikaverpil commented 2 months ago

Why this change?

I'm writing my own neotest adapter and I'm sending in error messages along with line numbers:

---@type string
local matched_line_number = string.match(line.Output, test_filename .. ":(%d+)")

---@type number | nil
local line_number = tonumber(matched_line_number)

if line_number ~= nil then
  ---@type neotest.Error
  error = { message = line.Output, line = line_number }
else
  ---@type neotest.Error
  error = { message = line.Output }
end

Full source here.

Sometimes, and only when a line number (an integer) is sent in, I see this crash in Neovim, and neotest breaks:

   Error  15:32:53 msg_show.lua_error Error executing vim.schedule lua callback: ...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:95: Async task failed without callback: The coroutine failed with this message: 
...redrik/lazy/neotest/lua/neotest/consumers/diagnostic.lua:103: attempt to perform arithmetic on a nil value
stack traceback:
    ...redrik/lazy/neotest/lua/neotest/consumers/diagnostic.lua: in function 'create_diagnostics'
    ...redrik/lazy/neotest/lua/neotest/consumers/diagnostic.lua:54: in function 'draw_buffer'
    ...redrik/lazy/neotest/lua/neotest/consumers/diagnostic.lua:167: in function 'draw_buffer'
    ...redrik/lazy/neotest/lua/neotest/consumers/diagnostic.lua:229: in function 'listener'
    .../fredrik/lazy/neotest/lua/neotest/client/events/init.lua:51: in function <.../fredrik/lazy/neotest/lua/neotest/client/events/init.lua:47>
stack traceback:
    [C]: in function 'error'
    ...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:95: in function 'close_task'
    ...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:117: in function 'cb'
    ...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:183: in function <...rik/.local/share/fredrik/lazy/nvim-nio/lua/nio/tasks.lua:182>

Turns out that the function call (found on line diagnostic.lua:103) can return either integer or nil, and it's not a good idea to subtract 1 from its return value without first checking it for being nil:

https://github.com/nvim-neotest/neotest/blob/a11ceb22507f61f8299c7d646259c6ef2e8017f9/lua/neotest/consumers/diagnostic.lua#L103

Function signature:

function string.find(s: string|number, pattern: string|number, init?: integer, plain?: boolean)
  -> start: integer|nil
  2. end: integer|nil
  3. ...any

What was done in this PR?

Instead of attempting to subtract 1 from potentially nil, I first check if the returned value is nil or not.

This completely remedies the crash and the error is now shown as expected in the buffer, which is very nice.

Notes

rcarriga commented 2 months ago

Great thanks for the PR!