patch 8.2.1236: Vim9: a few errors not caught by try/catch

Problem:    Vim9: a few errors not caught by try/catch.
Solution:   Do not bail out if an error is inside try/catch.  Fix that a not
            matching catch doesn't jump to :endtry.
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 88979af..ce12781 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1241,7 +1241,7 @@
 		    if (msg != NULL)
 		    {
 			emsg(_(msg));
-			goto failed;
+			goto on_error;
 		    }
 		}
 		break;
@@ -1272,7 +1272,8 @@
 		--ectx.ec_stack.ga_len;
 		if (set_vim_var_tv(iptr->isn_arg.number, STACK_TV_BOT(0))
 								       == FAIL)
-		    goto failed;
+		    // should not happen, type is checked when compiling
+		    goto on_error;
 		break;
 
 	    // store g:/b:/w:/t: variable
@@ -1335,7 +1336,7 @@
 		    if (lidx < 0 || lidx > list->lv_len)
 		    {
 			semsg(_(e_listidx), lidx);
-			goto failed;
+			goto on_error;
 		    }
 		    tv = STACK_TV_BOT(-3);
 		    if (lidx < list->lv_len)
@@ -1348,7 +1349,7 @@
 		    }
 		    else
 		    {
-			// append to list
+			// append to list, only fails when out of memory
 			if (list_append_tv(list, tv) == FAIL)
 			    goto failed;
 			clear_tv(tv);
@@ -1371,18 +1372,19 @@
 		    if (key == NULL || *key == NUL)
 		    {
 			emsg(_(e_emptykey));
-			goto failed;
+			goto on_error;
 		    }
 		    tv = STACK_TV_BOT(-3);
 		    di = dict_find(dict, key, -1);
 		    if (di != NULL)
 		    {
+			// overwrite existing value
 			clear_tv(&di->di_tv);
 			di->di_tv = *tv;
 		    }
 		    else
 		    {
-			// add to dict
+			// add to dict, only fails when out of memory
 			if (dict_add_tv(dict, (char *)key, tv) == FAIL)
 			    goto failed;
 			clear_tv(tv);
@@ -1465,7 +1467,7 @@
 	    case ISN_UNLET:
 		if (do_unlet(iptr->isn_arg.unlet.ul_name,
 				       iptr->isn_arg.unlet.ul_forceit) == FAIL)
-		    goto failed;
+		    goto on_error;
 		break;
 	    case ISN_UNLETENV:
 		vim_unsetenv(iptr->isn_arg.unlet.ul_name);
@@ -1481,24 +1483,38 @@
 	    // create a dict from items on the stack
 	    case ISN_NEWDICT:
 		{
-		    int	    count = iptr->isn_arg.number;
-		    dict_T  *dict = dict_alloc();
-		    dictitem_T *item;
+		    int		count = iptr->isn_arg.number;
+		    dict_T	*dict = dict_alloc();
+		    dictitem_T	*item;
 
 		    if (dict == NULL)
 			goto failed;
 		    for (idx = 0; idx < count; ++idx)
 		    {
-			// check key type is VAR_STRING
+			// have already checked key type is VAR_STRING
 			tv = STACK_TV_BOT(2 * (idx - count));
+			// check key is unique
+			item = dict_find(dict, tv->vval.v_string, -1);
+			if (item != NULL)
+			{
+			    semsg(_(e_duplicate_key), tv->vval.v_string);
+			    dict_unref(dict);
+			    goto on_error;
+			}
 			item = dictitem_alloc(tv->vval.v_string);
 			clear_tv(tv);
 			if (item == NULL)
+			{
+			    dict_unref(dict);
 			    goto failed;
+			}
 			item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
 			item->di_tv.v_lock = 0;
 			if (dict_add(dict, item) == FAIL)
+			{
+			    dict_unref(dict);
 			    goto failed;
+			}
 		    }
 
 		    if (count > 0)
@@ -1519,7 +1535,7 @@
 		if (call_dfunc(iptr->isn_arg.dfunc.cdf_idx,
 			      iptr->isn_arg.dfunc.cdf_argcount,
 			      &ectx) == FAIL)
-		    goto failed;
+		    goto on_error;
 		break;
 
 	    // call a builtin function