summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-10-05 20:49:35 +0200
committergolfinq <golfinqz@gmail.com>2023-10-02 14:23:11 -0400
commit5efbed51cce62cdd9a2927638030e76bf688cdf7 (patch)
tree1880ba45a1dce852ded71b665567d0382af5b933 /modules
parent0ca8542329888e8dccba89d59d3b728090c29991 (diff)
downloadredot-engine-5efbed51cce62cdd9a2927638030e76bf688cdf7.tar.gz
GDScript: Improve error messages for invalid indexing
These errors are very common when using an invalid property name or calling on an object of the wrong type, and the previous message was a bit cryptic for users. Co-authored-by: Rémi Verschelde <rverschelde@gmail.com> Co-authored-by: golfinq <golfinqz@gmail.com>
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp2
-rw-r--r--modules/gdscript/gdscript_vm.cpp45
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out2
8 files changed, 35 insertions, 24 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 882c246706..4c55573e59 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -3595,7 +3595,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
switch (base.builtin_type) {
case Variant::NIL: {
if (base.is_hard_type()) {
- push_error(vformat(R"(Invalid get index "%s" on base Nil)", name), p_identifier);
+ push_error(vformat(R"(Cannot get property "%s" on a null object.)", name), p_identifier);
}
return;
}
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index be18dee2cf..c0edaf5f65 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -888,8 +888,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(value, 2);
bool valid;
+#ifdef DEBUG_ENABLED
+ Variant::VariantSetError err_code;
+ dst->set(*index, *value, &valid, &err_code);
+#else
dst->set(*index, *value, &valid);
-
+#endif
#ifdef DEBUG_ENABLED
if (!valid) {
Object *obj = dst->get_validated_object();
@@ -906,7 +910,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
v = "of type '" + _get_var_type(index) + "'";
}
- err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'";
+ err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
+ if (err_code == Variant::VariantSetError::SET_INDEXED_ERR) {
+ err_text = "Invalid assignment of index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
+ }
}
OPCODE_BREAK;
}
@@ -937,7 +944,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
v = "of type '" + _get_var_type(index) + "'";
}
- err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'";
+ err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
OPCODE_BREAK;
}
#endif
@@ -987,7 +994,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool valid;
#ifdef DEBUG_ENABLED
// Allow better error message in cases where src and dst are the same stack position.
- Variant ret = src->get(*index, &valid);
+ Variant::VariantGetError err_code;
+ Variant ret = src->get(*index, &valid, &err_code);
#else
*dst = src->get(*index, &valid);
@@ -1000,7 +1008,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
v = "of type '" + _get_var_type(index) + "'";
}
- err_text = "Invalid get index " + v + " (on base: '" + _get_var_type(src) + "').";
+ err_text = "Invalid access to property or key " + v + " on a base object of type '" + _get_var_type(src) + "'.";
+ if (err_code == Variant::VariantGetError::GET_INDEXED_ERR) {
+ err_text = "Invalid access of index " + v + " on a base object of type: '" + _get_var_type(src) + "'.";
+ }
OPCODE_BREAK;
}
*dst = ret;
@@ -1036,7 +1047,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
v = "of type '" + _get_var_type(key) + "'";
}
- err_text = "Invalid get index " + v + " (on base: '" + _get_var_type(src) + "').";
+ err_text = "Invalid access to property or key " + v + " on a base object of type '" + _get_var_type(src) + "'.";
OPCODE_BREAK;
}
*dst = ret;
@@ -1101,7 +1112,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (read_only_property) {
err_text = vformat(R"(Cannot set value into property "%s" (on base "%s") because it is read-only.)", String(*index), _get_var_type(dst));
} else {
- err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
+ err_text = "Invalid assignment of property or key '" + String(*index) + "' with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
}
OPCODE_BREAK;
}
@@ -1146,7 +1157,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
#ifdef DEBUG_ENABLED
if (!valid) {
- err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
+ err_text = "Invalid access to property or key '" + index->operator String() + "' on a base object of type '" + _get_var_type(src) + "'.";
OPCODE_BREAK;
}
*dst = ret;
@@ -2619,7 +2630,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
Variant::construct(ret_type, retvalue, const_cast<const Variant **>(&r), 1, ce);
} else {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
Variant::get_type_name(r->get_type()), Variant::get_type_name(ret_type));
#endif // DEBUG_ENABLED
@@ -2649,9 +2660,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (r->get_type() != Variant::ARRAY) {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return a value of type "%s" where expected return type is "Array[%s]".)",
- _get_var_type(r), _get_element_type(builtin_type, native_type, *script_type));
-#endif // DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "Array[%s]".)",
+ Variant::get_type_name(r->get_type()), Variant::get_type_name(builtin_type));
+#endif
OPCODE_BREAK;
}
@@ -2682,7 +2693,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GD_ERR_BREAK(!nc);
if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
Variant::get_type_name(r->get_type()), nc->get_name());
OPCODE_BREAK;
}
@@ -2700,7 +2711,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif // DEBUG_ENABLED
if (ret_obj && !ClassDB::is_parent_class(ret_obj->get_class_name(), nc->get_name())) {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
ret_obj->get_class_name(), nc->get_name());
#endif // DEBUG_ENABLED
OPCODE_BREAK;
@@ -2723,7 +2734,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
Variant::get_type_name(r->get_type()), GDScript::debug_get_script_name(Ref<Script>(base_type)));
#endif // DEBUG_ENABLED
OPCODE_BREAK;
@@ -2745,7 +2756,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
ScriptInstance *ret_inst = ret_obj->get_script_instance();
if (!ret_inst) {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
ret_obj->get_class_name(), GDScript::debug_get_script_name(Ref<GDScript>(base_type)));
#endif // DEBUG_ENABLED
OPCODE_BREAK;
@@ -2764,7 +2775,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (!valid) {
#ifdef DEBUG_ENABLED
- err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
GDScript::debug_get_script_name(ret_obj->get_script_instance()->get_script()), GDScript::debug_get_script_name(Ref<GDScript>(base_type)));
#endif // DEBUG_ENABLED
OPCODE_BREAK;
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out
index 73a54d7820..a6a3973255 100644
--- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out
+++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> analyzer/errors/outer_class_constants.gd
>> 8
->> Invalid get index 'OUTER_CONST' (on base: 'GDScript').
+>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'GDScript'.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out
index 92e7b9316e..70fdc5b62c 100644
--- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out
+++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> analyzer/errors/outer_class_constants_as_variant.gd
>> 9
->> Invalid get index 'OUTER_CONST' (on base: 'GDScript').
+>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'GDScript'.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out
index 892f8e2c3f..6632f056bd 100644
--- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out
+++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> analyzer/errors/outer_class_instance_constants.gd
>> 8
->> Invalid get index 'OUTER_CONST' (on base: 'RefCounted (Inner)').
+>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'RefCounted (Inner)'.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out
index 8257e74f57..0459b756d1 100644
--- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out
+++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> analyzer/errors/outer_class_instance_constants_as_variant.gd
>> 9
->> Invalid get index 'OUTER_CONST' (on base: 'RefCounted (Inner)').
+>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'RefCounted (Inner)'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out b/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out
index 2a97eaea44..c524a1ae6b 100644
--- a/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out
+++ b/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> runtime/errors/constant_array_is_deep.gd
>> 6
->> Invalid set index '0' (on base: 'Dictionary') with value of type 'int'
+>> Invalid assignment of property or key '0' with value of type 'int' on a base object of type 'Dictionary'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out b/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out
index c807db6b0c..cf51b0262d 100644
--- a/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out
+++ b/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out
@@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR
>> on function: test()
>> runtime/errors/constant_dictionary_is_deep.gd
>> 6
->> Invalid set index '0' (on base: 'Array') with value of type 'int'
+>> Invalid assignment of index '0' (on base: 'Array') with value of type 'int'.