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

This commit is contained in:
Juan Linietsky 2016-06-11 19:43:38 -03:00
parent d5e2b59c84
commit f860915ae0
3 changed files with 56 additions and 23 deletions

View File

@ -727,7 +727,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
String methodstr = GDFunctions::get_func_name(func); 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; break;
} }
ip+=argc+1; ip+=argc+1;

View File

@ -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) {\ if (p_arg_count<m_count) {\
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;\ r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;\
r_error.argument=m_count;\ r_error.argument=m_count;\
r_ret=Variant();\
return;\ return;\
}\ }\
if (p_arg_count>m_count) {\ if (p_arg_count>m_count) {\
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\ r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\
r_error.argument=m_count;\ r_error.argument=m_count;\
r_ret=Variant();\
return;\ 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
r_error.argument=m_arg;\ r_error.argument=m_arg;\
r_error.expected=Variant::REAL;\ r_error.expected=Variant::REAL;\
r_ret=Variant();\
return;\ 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::REAL; r_error.expected=Variant::REAL;
r_ret=Variant();
} }
} break; } break;
case MATH_SIGN: { 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::REAL; r_error.expected=Variant::REAL;
r_ret=Variant();
} }
} break; } break;
case MATH_POW: { 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=Variant();
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=Variant(); r_ret=Variant();
return; 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]; int type=*p_args[1];
if (type<0 || type>=Variant::VARIANT_MAX) { if (type<0 || type>=Variant::VARIANT_MAX) {
ERR_PRINT("Invalid type argument to convert()"); r_ret=RTR("Invalid type argument to convert(), use TYPE_* constants.");
r_ret=Variant::NIL; r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
r_error.expected=Variant::INT;
return;
} else { } 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::STRING; r_error.expected=Variant::STRING;
r_ret=Variant(); r_ret="Parse error at line "+itos(line)+": "+errs;
return;
} }
} break; } 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::NIL; r_error.expected=Variant::NIL;
r_ret=Variant(); r_ret="Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
return; 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(); ByteArray::Read r=varr.read();
Error err = decode_variant(ret,r.ptr(),varr.size(),NULL); Error err = decode_variant(ret,r.ptr(),varr.size(),NULL);
if (err!=OK) { 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::RAW_ARRAY; r_error.expected=Variant::RAW_ARRAY;
r_ret=Variant();
return; 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.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=1; r_error.argument=1;
r_ret=Variant();
} break; } break;
case 1: { 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]; int incr=*p_args[2];
if (incr==0) { 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; r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL(); return;
} }
Array arr(true); 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.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=3; r_error.argument=3;
r_ret=Variant();
} break; } 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::DICTIONARY; r_error.expected=Variant::DICTIONARY;
ERR_PRINT("Not a script with an instance"); r_ret=RTR("Not a script with an instance");
return;
} else { } else {
GDInstance *ins = static_cast<GDInstance*>(obj->get_script_instance()); 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::DICTIONARY; r_error.expected=Variant::DICTIONARY;
ERR_PRINT("Not based on a script"); r_ret=RTR("Not based on a script");
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::DICTIONARY; r_error.expected=Variant::DICTIONARY;
print_line("PATH: "+p->path); r_ret=Variant();
ERR_PRINT("Not based on a resource file");
r_ret=RTR("Not based on a resource file");
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::DICTIONARY; r_error.expected=Variant::DICTIONARY;
r_ret=Variant();
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=RTR("Invalid instance dictionary format (missing @path)");
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=RTR("Invalid instance dictionary format (can't load script at @path)");
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=Variant();
r_ret=RTR("Invalid instance dictionary format (invalid script at @path)");
return; 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::OBJECT; r_error.expected=Variant::OBJECT;
r_ret=Variant();
r_ret=RTR("Invalid instance dictionary (invalid subclasses)");
return; return;
} }
} }
r_ret = gdscr->_new(NULL,0,r_error); r_ret = gdscr->_new(NULL,0,r_error);
GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance()); GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance());
Ref<GDScript> gd_ref = ins->get_script(); Ref<GDScript> gd_ref = ins->get_script();
for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) { for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) {
if(d.has(E->key())) { if(d.has(E->key())) {
ins->members[E->get().index] = d[E->key()]; ins->members[E->get().index] = d[E->key()];
} }
} }
} break; } break;
case HASH: { 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) { if (p_arg_count<3) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=3; r_error.argument=3;
r_ret=Variant();
return; return;
} }
if (p_arg_count>4) { if (p_arg_count>4) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=4; r_error.argument=4;
r_ret=Variant();
return; 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) { 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.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0; r_error.argument=0;
r_error.expected=Variant::INT;
r_ret=Variant(); r_ret=Variant();
break; break;
} }

View File

@ -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_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_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") );
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") ); 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_ON_EXPAND );
BIND_CONSTANT( STRETCH_SCALE ); BIND_CONSTANT( STRETCH_SCALE );