Browse Source

Made many built-in gdscript functions return more descriptive errors, closes #5150

Juan Linietsky 9 years ago
parent
commit
f860915ae0
3 changed files with 56 additions and 23 deletions
  1. 6 1
      modules/gdscript/gd_function.cpp
  2. 49 21
      modules/gdscript/gd_functions.cpp
  3. 1 1
      scene/gui/texture_frame.cpp

+ 6 - 1
modules/gdscript/gd_function.cpp

@@ -727,7 +727,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
 
 
 					String methodstr = GDFunctions::get_func_name(func);
-					err_text=_get_call_error(err,"built-in function '"+methodstr+"'",(const Variant**)argptrs);
+					if (dst->get_type()==Variant::STRING) {
+						//call provided error string
+						err_text="Error calling built-in function '"+methodstr+"': "+String(*dst);
+					} else {
+						err_text=_get_call_error(err,"built-in function '"+methodstr+"'",(const Variant**)argptrs);
+					}
 					break;
 				}
 				ip+=argc+1;

+ 49 - 21
modules/gdscript/gd_functions.cpp

@@ -120,11 +120,13 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 	if (p_arg_count<m_count) {\
 		r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;\
 		r_error.argument=m_count;\
+		r_ret=Variant();\
 		return;\
 	}\
 	if (p_arg_count>m_count) {\
 		r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\
 		r_error.argument=m_count;\
+		r_ret=Variant();\
 		return;\
 	}
 
@@ -133,6 +135,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 		r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
 		r_error.argument=m_arg;\
 		r_error.expected=Variant::REAL;\
+		r_ret=Variant();\
 		return;\
 	}
 
@@ -244,6 +247,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::REAL;
+				r_ret=Variant();
 			}
 		} break;
 		case MATH_SIGN: {
@@ -261,6 +265,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 					r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument=0;
 					r_error.expected=Variant::REAL;
+					r_ret=Variant();
 				}
 		} break;
 		case MATH_POW: {
@@ -442,6 +447,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::OBJECT;
+				r_ret=Variant();
 				return;
 
 			}
@@ -479,7 +485,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::OBJECT;
-				r_ret=Variant();
+				r_ret=Variant();				
 				return;
 
 			}
@@ -508,8 +514,11 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 			int type=*p_args[1];
 			if (type<0 || type>=Variant::VARIANT_MAX) {
 
-				ERR_PRINT("Invalid type argument to convert()");
-				r_ret=Variant::NIL;
+				r_ret=RTR("Invalid type argument to convert(), use TYPE_* constants.");
+				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.argument=0;
+				r_error.expected=Variant::INT;
+				return;
 
 			} else {
 
@@ -638,7 +647,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::STRING;
-				r_ret=Variant();
+				r_ret="Parse error at line "+itos(line)+": "+errs;
+				return;
 			}
 
 		} break;
@@ -652,7 +662,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::NIL;
-				r_ret=Variant();
+				r_ret="Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
 				return;
 			}
 
@@ -680,11 +690,10 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				ByteArray::Read r=varr.read();
 				Error err = decode_variant(ret,r.ptr(),varr.size(),NULL);
 				if (err!=OK) {
-					ERR_PRINT("Not enough bytes for decoding..");
+					r_ret=RTR("Not enough bytes for decoding bytes, or invalid format.");
 					r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument=0;
 					r_error.expected=Variant::RAW_ARRAY;
-					r_ret=Variant();
 					return;
 				}
 
@@ -701,6 +710,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 
 					r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 					r_error.argument=1;
+					r_ret=Variant();
 
 				} break;
 				case 1: {
@@ -759,9 +769,9 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 					int incr=*p_args[2];
 					if (incr==0) {
 
-						ERR_EXPLAIN("step argument is zero!");
+						r_ret=RTR("step argument is zero!");
 						r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
-						ERR_FAIL();
+						return;
 					}
 
 					Array arr(true);
@@ -812,6 +822,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 
 					r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 					r_error.argument=3;
+					r_ret=Variant();
+
 				} break;
 			}
 
@@ -847,8 +859,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 					r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument=0;
 					r_error.expected=Variant::DICTIONARY;
-					ERR_PRINT("Not a script with an instance");
-
+					r_ret=RTR("Not a script with an instance");
+					return;
 				} else {
 
 					GDInstance *ins = static_cast<GDInstance*>(obj->get_script_instance());
@@ -858,7 +870,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 						r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 						r_error.argument=0;
 						r_error.expected=Variant::DICTIONARY;
-						ERR_PRINT("Not based on a script");
+						r_ret=RTR("Not based on a script");
 						return;
 
 					}
@@ -879,8 +891,10 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 						r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 						r_error.argument=0;
 						r_error.expected=Variant::DICTIONARY;
-						print_line("PATH: "+p->path);
-						ERR_PRINT("Not based on a resource file");
+						r_ret=Variant();
+
+
+						r_ret=RTR("Not based on a resource file");
 
 						return;
 					}
@@ -926,6 +940,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::DICTIONARY;
+				r_ret=Variant();
+
 				return;
 			}
 
@@ -936,6 +952,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::OBJECT;
+				r_ret=RTR("Invalid instance dictionary format (missing @path)");
+
 				return;
 			}
 
@@ -945,6 +963,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::OBJECT;
+				r_ret=RTR("Invalid instance dictionary format (can't load script at @path)");
 				return;
 			}
 
@@ -955,6 +974,8 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
 				r_error.expected=Variant::OBJECT;
+				r_ret=Variant();
+				r_ret=RTR("Invalid instance dictionary format (invalid script at @path)");
 				return;
 			}
 
@@ -971,20 +992,22 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 					r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument=0;
 					r_error.expected=Variant::OBJECT;
+					r_ret=Variant();
+					r_ret=RTR("Invalid instance dictionary (invalid subclasses)");
 					return;
 				}
 			}
 
 			r_ret = gdscr->_new(NULL,0,r_error);
 
-            GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance());
-            Ref<GDScript> gd_ref = ins->get_script();
+			GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance());
+			Ref<GDScript> gd_ref = ins->get_script();
 
-            for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) {
-                if(d.has(E->key())) {
-                    ins->members[E->get().index] = d[E->key()];
-                }
-            }
+			for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) {
+				if(d.has(E->key())) {
+					ins->members[E->get().index] = d[E->key()];
+				}
+			}
 
 		} break;
 		case HASH: {
@@ -998,11 +1021,15 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 			if (p_arg_count<3) {
 				r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 				r_error.argument=3;
+				r_ret=Variant();
+
 				return;
 			}
 			if (p_arg_count>4) {
 				r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 				r_error.argument=4;
+				r_ret=Variant();
+
 				return;
 			}
 
@@ -1036,6 +1063,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
 			if (p_args[0]->get_type()!=Variant::INT && p_args[0]->get_type()!=Variant::REAL) {
 				r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument=0;
+				r_error.expected=Variant::INT;
 				r_ret=Variant();
 				break;
 			}

+ 1 - 1
scene/gui/texture_frame.cpp

@@ -127,7 +127,7 @@ void TextureFrame::_bind_methods() {
 	ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") );
 	ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") );
 	ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") );
-	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "stretch_mode",PROPERTY_HINT_ENUM,"Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Scale Keep Aspect,Scale Keep Aspect Centered"), _SCS("set_stretch_mode"),_SCS("get_stretch_mode") );
+	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "stretch_mode",PROPERTY_HINT_ENUM,"Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered"), _SCS("set_stretch_mode"),_SCS("get_stretch_mode") );
 
 	BIND_CONSTANT( STRETCH_SCALE_ON_EXPAND );
 	BIND_CONSTANT( STRETCH_SCALE );