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,7 +1193,8 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
|
|||||||
if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
|
if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
|
||||||
{
|
{
|
||||||
emsg_severe = TRUE;
|
emsg_severe = TRUE;
|
||||||
semsg(_(e_trailing_arg), arg);
|
if (!error)
|
||||||
|
semsg(_(e_trailing_arg), arg);
|
||||||
break;
|
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
|
EXTERN int did_emsg_cumul; // cumulative did_emsg, increased
|
||||||
// when did_emsg is reset.
|
// when did_emsg is reset.
|
||||||
EXTERN int called_vim_beep; // set if vim_beep() is called
|
EXTERN int called_vim_beep; // set if vim_beep() is called
|
||||||
EXTERN int did_uncaught_emsg; // emsg() was called and did not
|
EXTERN int uncaught_emsg; // number of times emsg() was
|
||||||
// cause an exception
|
// called and did show a message
|
||||||
#endif
|
#endif
|
||||||
EXTERN int did_emsg_syntax; // did_emsg set because of a
|
EXTERN int did_emsg_syntax; // did_emsg set because of a
|
||||||
// syntax error
|
// syntax error
|
||||||
|
@@ -733,7 +733,7 @@ emsg_core(char_u *s)
|
|||||||
flush_buffers(FLUSH_MINIMAL); // flush internal buffers
|
flush_buffers(FLUSH_MINIMAL); // flush internal buffers
|
||||||
++did_emsg; // flag for DoOneCmd()
|
++did_emsg; // flag for DoOneCmd()
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
did_uncaught_emsg = TRUE;
|
++uncaught_emsg;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -160,6 +160,52 @@ def Test_autoload_names()
|
|||||||
delete(dir, 'rf')
|
delete(dir, 'rf')
|
||||||
enddef
|
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
|
def CallRecursive(n: number): number
|
||||||
return CallRecursive(n + 1)
|
return CallRecursive(n + 1)
|
||||||
enddef
|
enddef
|
||||||
|
@@ -12,10 +12,10 @@ func CheckDefSuccess(lines)
|
|||||||
try
|
try
|
||||||
exe 'so ' .. fname
|
exe 'so ' .. fname
|
||||||
call Func()
|
call Func()
|
||||||
delfunc! Func
|
|
||||||
finally
|
finally
|
||||||
call chdir(cwd)
|
call chdir(cwd)
|
||||||
call delete(fname)
|
call delete(fname)
|
||||||
|
delfunc! Func
|
||||||
endtry
|
endtry
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -520,6 +520,7 @@ check_due_timer(void)
|
|||||||
int save_timer_busy = timer_busy;
|
int save_timer_busy = timer_busy;
|
||||||
int save_vgetc_busy = vgetc_busy;
|
int save_vgetc_busy = vgetc_busy;
|
||||||
int save_did_emsg = did_emsg;
|
int save_did_emsg = did_emsg;
|
||||||
|
int prev_uncaught_emsg = uncaught_emsg;
|
||||||
int save_called_emsg = called_emsg;
|
int save_called_emsg = called_emsg;
|
||||||
int save_must_redraw = must_redraw;
|
int save_must_redraw = must_redraw;
|
||||||
int save_trylevel = trylevel;
|
int save_trylevel = trylevel;
|
||||||
@@ -536,7 +537,6 @@ check_due_timer(void)
|
|||||||
vgetc_busy = 0;
|
vgetc_busy = 0;
|
||||||
called_emsg = 0;
|
called_emsg = 0;
|
||||||
did_emsg = FALSE;
|
did_emsg = FALSE;
|
||||||
did_uncaught_emsg = FALSE;
|
|
||||||
must_redraw = 0;
|
must_redraw = 0;
|
||||||
trylevel = 0;
|
trylevel = 0;
|
||||||
did_throw = FALSE;
|
did_throw = FALSE;
|
||||||
@@ -555,7 +555,7 @@ check_due_timer(void)
|
|||||||
did_one = TRUE;
|
did_one = TRUE;
|
||||||
timer_busy = save_timer_busy;
|
timer_busy = save_timer_busy;
|
||||||
vgetc_busy = save_vgetc_busy;
|
vgetc_busy = save_vgetc_busy;
|
||||||
if (did_uncaught_emsg)
|
if (uncaught_emsg > prev_uncaught_emsg)
|
||||||
++timer->tr_emsg_count;
|
++timer->tr_emsg_count;
|
||||||
did_emsg = save_did_emsg;
|
did_emsg = save_did_emsg;
|
||||||
called_emsg = save_called_emsg;
|
called_emsg = save_called_emsg;
|
||||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3341,
|
||||||
/**/
|
/**/
|
||||||
3340,
|
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
|
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)
|
if (ufunc == NULL)
|
||||||
{
|
{
|
||||||
int called_emsg_before = called_emsg;
|
int prev_uncaught_emsg = uncaught_emsg;
|
||||||
|
|
||||||
if (script_autoload(name, TRUE))
|
if (script_autoload(name, TRUE))
|
||||||
// loaded a package, search for the function again
|
// loaded a package, search for the function again
|
||||||
ufunc = find_func(name, FALSE, NULL);
|
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
|
return FAIL; // bail out if loading the script caused an error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user