0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.3341: Vim9: function call aborted despite try/catch

Problem:    Vim9: function call aborted despite try/catch. (Naohiro Ono)
Solution:   Ignore error caught by try/catch. (closes #8755)
This commit is contained in:
Bram Moolenaar
2021-08-14 14:01:05 +02:00
parent 78a9c2e670
commit 88c89c7722
8 changed files with 63 additions and 12 deletions

View File

@@ -1193,6 +1193,7 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
{
emsg_severe = TRUE;
if (!error)
semsg(_(e_trailing_arg), arg);
break;
}

View File

@@ -238,8 +238,8 @@ EXTERN int did_emsg_def; // set by emsg() when emsg_silent
EXTERN int did_emsg_cumul; // cumulative did_emsg, increased
// when did_emsg is reset.
EXTERN int called_vim_beep; // set if vim_beep() is called
EXTERN int did_uncaught_emsg; // emsg() was called and did not
// cause an exception
EXTERN int uncaught_emsg; // number of times emsg() was
// called and did show a message
#endif
EXTERN int did_emsg_syntax; // did_emsg set because of a
// syntax error

View File

@@ -733,7 +733,7 @@ emsg_core(char_u *s)
flush_buffers(FLUSH_MINIMAL); // flush internal buffers
++did_emsg; // flag for DoOneCmd()
#ifdef FEAT_EVAL
did_uncaught_emsg = TRUE;
++uncaught_emsg;
#endif
}

View File

@@ -160,6 +160,52 @@ def Test_autoload_names()
delete(dir, 'rf')
enddef
def Test_autoload_error_in_script()
var dir = 'Xdir/autoload'
mkdir(dir, 'p')
var lines =<< trim END
func scripterror#function()
let g:called_function = 'yes'
endfunc
let 0 = 1
END
writefile(lines, dir .. '/scripterror.vim')
var save_rtp = &rtp
exe 'set rtp=' .. getcwd() .. '/Xdir'
g:called_function = 'no'
# The error in the autoload script cannot be checked with assert_fails(), use
# CheckDefSuccess() instead of CheckDefFailure()
try
CheckDefSuccess(['scripterror#function()'])
catch
assert_match('E121: Undefined variable: 0', v:exception)
endtry
assert_equal('no', g:called_function)
lines =<< trim END
func scriptcaught#function()
let g:called_function = 'yes'
endfunc
try
let 0 = 1
catch
let g:caught = v:exception
endtry
END
writefile(lines, dir .. '/scriptcaught.vim')
g:called_function = 'no'
CheckDefSuccess(['scriptcaught#function()'])
assert_match('E121: Undefined variable: 0', g:caught)
assert_equal('yes', g:called_function)
&rtp = save_rtp
delete(dir, 'rf')
enddef
def CallRecursive(n: number): number
return CallRecursive(n + 1)
enddef

View File

@@ -12,10 +12,10 @@ func CheckDefSuccess(lines)
try
exe 'so ' .. fname
call Func()
delfunc! Func
finally
call chdir(cwd)
call delete(fname)
delfunc! Func
endtry
endfunc

View File

@@ -520,6 +520,7 @@ check_due_timer(void)
int save_timer_busy = timer_busy;
int save_vgetc_busy = vgetc_busy;
int save_did_emsg = did_emsg;
int prev_uncaught_emsg = uncaught_emsg;
int save_called_emsg = called_emsg;
int save_must_redraw = must_redraw;
int save_trylevel = trylevel;
@@ -536,7 +537,6 @@ check_due_timer(void)
vgetc_busy = 0;
called_emsg = 0;
did_emsg = FALSE;
did_uncaught_emsg = FALSE;
must_redraw = 0;
trylevel = 0;
did_throw = FALSE;
@@ -555,7 +555,7 @@ check_due_timer(void)
did_one = TRUE;
timer_busy = save_timer_busy;
vgetc_busy = save_vgetc_busy;
if (did_uncaught_emsg)
if (uncaught_emsg > prev_uncaught_emsg)
++timer->tr_emsg_count;
did_emsg = save_did_emsg;
called_emsg = save_called_emsg;

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3341,
/**/
3340,
/**/

View File

@@ -844,12 +844,13 @@ may_restore_cmdmod(funclocal_T *funclocal)
}
/*
* Return TRUE if an error was given or CTRL-C was pressed.
* Return TRUE if an error was given (not caught in try/catch) or CTRL-C was
* pressed.
*/
static int
vim9_aborting(int prev_called_emsg)
vim9_aborting(int prev_uncaught_emsg)
{
return called_emsg > prev_called_emsg || got_int || did_throw;
return uncaught_emsg > prev_uncaught_emsg || got_int || did_throw;
}
/*
@@ -882,12 +883,13 @@ call_by_name(
if (ufunc == NULL)
{
int called_emsg_before = called_emsg;
int prev_uncaught_emsg = uncaught_emsg;
if (script_autoload(name, TRUE))
// loaded a package, search for the function again
ufunc = find_func(name, FALSE, NULL);
if (vim9_aborting(called_emsg_before))
if (vim9_aborting(prev_uncaught_emsg))
return FAIL; // bail out if loading the script caused an error
}