diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2022-08-30 23:13:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-30 23:13:52 +0100 |
commit | 813476bf7291dfaf9fc0ef77c9f53a07258a3801 (patch) | |
tree | d31ff4fa8f0b214f03172ec0473c1a22b8ed0139 /test/functional/vimscript/eval_spec.lua | |
parent | 6b7eed1884c3b022cc15568c39f80f8f4da0780b (diff) | |
download | rneovim-813476bf7291dfaf9fc0ef77c9f53a07258a3801.tar.gz rneovim-813476bf7291dfaf9fc0ef77c9f53a07258a3801.tar.bz2 rneovim-813476bf7291dfaf9fc0ef77c9f53a07258a3801.zip |
fix(exceptions): restore `did_throw` (#20000)
`!did_throw` doesn't exactly imply `!current_exception`, as `did_throw = false`
is sometimes used to defer exception handling for later (without forgetting the
exception). E.g: uncaught exception handling in `do_cmdline()` may be deferred
to a different call (e.g: when `try_level > 0`).
In #7881, `current_exception = NULL` in `do_cmdline()` is used as an analogue of
`did_throw = false`, but also causes the pending exception to be lost, which
also leaks as `discard_exception()` wasn't used.
It may be possible to fix this by saving/restoring `current_exception`, but
handling all of `did_throw`'s edge cases seems messier. Maybe not worth
diverging over.
This fix also uncovers a `man_spec.lua` bug on Windows: exceptions are thrown
due to Windows missing `man`, but they're lost; skip these tests if `man` isn't
executable.
Diffstat (limited to 'test/functional/vimscript/eval_spec.lua')
-rw-r--r-- | test/functional/vimscript/eval_spec.lua | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index 65ac5b8c80..d4fa7afe89 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -219,3 +219,31 @@ it('Error when if/for/while/try/function is nested too deep',function() feed(':call Test5()<CR>') screen:expect({any = 'E1058: '}) end) + +describe("uncaught exception", function() + before_each(clear) + after_each(function() + os.remove('throw1.vim') + os.remove('throw2.vim') + os.remove('throw3.vim') + end) + + it('is not forgotten #13490', function() + command('autocmd BufWinEnter * throw "i am error"') + eq('i am error', exc_exec('try | new | endtry')) + + -- Like Vim, throwing here aborts the processing of the script, but does not stop :runtime! + -- from processing the others. + -- Only the first thrown exception should be rethrown from the :try below, though. + for i = 1, 3 do + write_file('throw' .. i .. '.vim', ([[ + let result ..= '%d' + throw 'throw%d' + let result ..= 'X' + ]]):format(i, i)) + end + command('set runtimepath+=. | let result = ""') + eq('throw1', exc_exec('try | runtime! throw*.vim | endtry')) + eq('123', eval('result')) + end) +end) |