]> granicus.if.org Git - vim/commitdiff
patch 8.2.3341: Vim9: function call aborted despite try/catch v8.2.3341
authorBram Moolenaar <Bram@vim.org>
Sat, 14 Aug 2021 12:01:05 +0000 (14:01 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 14 Aug 2021 12:01:05 +0000 (14:01 +0200)
Problem:    Vim9: function call aborted despite try/catch. (Naohiro Ono)
Solution:   Ignore error caught by try/catch. (closes #8755)

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

index 721b688d5835f6ba680122829739609a798202e1..86a66940414c6548d28239e049b256c772ddeaf4 100644 (file)
@@ -1193,7 +1193,8 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
            if (!VIM_ISWHITE(*arg) && !ends_excmd(*arg))
            {
                emsg_severe = TRUE;
-               semsg(_(e_trailing_arg), arg);
+               if (!error)
+                   semsg(_(e_trailing_arg), arg);
                break;
            }
        }
index f09ad482fbf7dc737e0bff7a84f7c42f5a594851..6d9741b6a186da4a5dc5d34d35929b270a74bc8a 100644 (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
index 23b84fa831bc375491ca5d1c34bcc7e32fff6982..bb0dbb2bd1bfebda113760dbf87d8698bfcdc41a 100644 (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
     }
 
index f8d3f59b2e3a510d6cf46021ac22c85498674f2a..cc7132aac990e49e0d91af7e3d9a2f6b3d0d0e4f 100644 (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
index 742a0932b5c8a532bd56ce5f2c33bf4bc1d89acd..a40b444b3de75797b5855b40dfe95aae91db8a0d 100644 (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
 
index ecd884f0f6c712d104d2b8c751d5be47d050c66d..ab12691980b0fbe1722a3bb8b35d705f1170925b 100644 (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;
index 87c315a7c83350b5371a34a870ba92b262fdcd59..e49611216293538c86c19c3f41bfbf5e6036c7ea 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3341,
 /**/
     3340,
 /**/
index 04d5e5f27cea3007ee8fa6b38ac756851d65eae5..4562a08bf4e130a49cdd5bced5814dd86b433873 100644 (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
     }