changeset 25609:f8bcd21e6e24 v8.2.3341

patch 8.2.3341: Vim9: function call aborted despite try/catch Commit: https://github.com/vim/vim/commit/88c89c77229e725ab2613b022249e2f506d82b82 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 14 14:01:05 2021 +0200 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 https://github.com/vim/vim/issues/8755)
author Bram Moolenaar <Bram@vim.org>
date Sat, 14 Aug 2021 14:15:03 +0200
parents 8b76de69fa55
children ac9f242ebb9e
files src/evalvars.c src/globals.h src/message.c src/testdir/test_vim9_func.vim src/testdir/vim9.vim src/time.c src/version.c src/vim9execute.c
diffstat 8 files changed, 63 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -1193,7 +1193,8 @@ list_arg_vars(exarg_T *eap, char_u *arg,
 	    if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
 	    {
 		emsg_severe = TRUE;
-		semsg(_(e_trailing_arg), arg);
+		if (!error)
+		    semsg(_(e_trailing_arg), arg);
 		break;
 	    }
 	}
--- a/src/globals.h
+++ b/src/globals.h
@@ -238,8 +238,8 @@ EXTERN int	did_emsg_def;		    // set by 
 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
--- a/src/message.c
+++ b/src/message.c
@@ -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
     }
 
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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
--- a/src/testdir/vim9.vim
+++ b/src/testdir/vim9.vim
@@ -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
 
--- a/src/time.c
+++ b/src/time.c
@@ -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;
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3341,
+/**/
     3340,
 /**/
     3339,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -844,12 +844,13 @@ may_restore_cmdmod(funclocal_T *funcloca
 }
 
 /*
- * 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
     }