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:
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3341,
|
||||
/**/
|
||||
3340,
|
||||
/**/
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user