-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve error message when a GDScript instance fails to be constructed #76632
Conversation
Thanks for opening a pull request! Please amend the commit to use a human-readable commit message ( |
Like this? |
This is much better already 🙂 To be more consistent with the existing Git history, I recommend using present tense and not finishing the commit message with a period:
|
Done. |
modules/gdscript/gdscript.cpp
Outdated
@@ -181,7 +181,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco | |||
MutexLock lock(GDScriptLanguage::singleton->mutex); | |||
instances.erase(p_owner); | |||
} | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance."); | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance. Make sure this script's _init() function can take 0 arguments."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably not the only possible cause of the error and we should check r_error.error
if we want to display more specific errors. For example, this case corresponds to CALL_ERROR_TOO_MANY_ARGUMENTS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I added printouts for r_error.error
.
modules/gdscript/gdscript.cpp
Outdated
@@ -181,7 +182,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco | |||
MutexLock lock(GDScriptLanguage::singleton->mutex); | |||
instances.erase(p_owner); | |||
} | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance."); | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + Variant::get_call_error_text(instance->owner, initializer->get_name(), p_args, p_argcount, r_error) + ". Ensure this script's _init() function can take 0 arguments."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + Variant::get_call_error_text(instance->owner, initializer->get_name(), p_args, p_argcount, r_error) + ". Ensure this script's _init() function can take 0 arguments."); | |
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + Variant::get_call_error_text(instance->owner, "_init", p_args, p_argcount, r_error)); |
I think the clarification is unrelated to other possible errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Pardon me, I'm not yet familiar with internal terminology.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is not changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. It was late last night. I actually fixed it now. I'm a little concerned that removing the clarification may make it so that some people may not understand what it means, but you're right that the clarification is unrelated to all but one of the possible errors in the enum and may lead people astray were they to occur.
I think this PR is just one of the necessary steps to close the issue. Also we need to add a note to the docs and a warning if |
Just a little more food for thought here! :) Might there be a way to do something similarly informative without including |
modules/gdscript/gdscript.cpp
Outdated
@@ -164,7 +165,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco | |||
MutexLock lock(GDScriptLanguage::singleton->mutex); | |||
instances.erase(p_owner); | |||
} | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance."); | |||
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + Variant::get_call_error_text(instance->owner, "@implicit_new", nullptr, 0, r_error)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably makes sense to move getting the error text before line 163, since it removes the script from the object.
godot/core/variant/variant.cpp
Lines 3678 to 3681 in ce75c46
Ref<Resource> script = p_base->get_script(); | |
if (script.is_valid() && script->get_path().is_resource_file()) { | |
base_text += "(" + script->get_path().get_file() + ")"; | |
} |
Lines 868 to 872 in e0e93ce
if (p_instance) { | |
script = p_instance->get_script(); | |
} else { | |
script = Variant(); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this something I should do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, does err_v stop the script? If it does, it's good to keep the memory freeing here before the message, to not cause a memory leak.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, ERR_FAIL_*
macros have return
. I think you should use a variable:
String error_text = Variant::get_call_error_text(...);
instance->owner->set_script_instance(nullptr);
...
ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so you're suggesting assigning the variable to grab the message before the script instance is removed, so that we make sure we get the right error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so, in this case the error text will contain the script file name, judging by the snippets that I have given above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good idea. I changed that just now.
I thought about that, but I would have to copy and paste the get call error text function. |
@anvilfolk does actually bring up a good point, though; should I instead copy the call message function into gdscript.cpp? Then, I can make the error messages more clear, since the function doesn't have to be for anything other than these errors. And then I can remove the header file, so it doesn't have to recompile. I'd hate to have my one little change to add a whole bunch of compile time. |
I'd love to have someone else's opinion on this for sure :) maybe it's not a big deal since I don't think Edit: I also just realized that it's an include from a |
I don't see why we shouldn't just copy the error message over, instead of adding another include to |
I went and checked and the function is still like ~30 lines of code. Not a ton, but definitely not the most trivial thing either - it checks for lots of different things. @SlashScreen do you need to check for all of those or do you think that you'd only need a small part of that function? If it really is just checking for one or two conditions, then copy-pasting here makes a ton of sense. Copy pasting 30 lines of code I'd be a little more worried about - especially if the copy pasting requires the includes anyway! :) |
Isn't Well, guess it doesn't hurt to import it neither. |
|
Since we appear to have determined that the include is less of an issue than copy and pasting the function (which I was already hesitant to do anyways, since it was setting off my mental Don't Repeat Yourself alarms), is there anything else that I need to address before the PR can be merged (not to sound too presumptuous)? |
🌵 🌵 🌵 🌵 DRY alarm! DRY alarm! 🌵 🌵 🌵 🌵 In seriousness, I'd remove the The other thing that might make folks a little more excited about this is if you showed the original error vs the new error in your PR description? I'd love to see it myself! |
Oh, I also just noticed that you have 9 commits. You should squash that into a single commit :) More information here: https://docs.godotengine.org/en/stable/contributing/workflow/pr_workflow.html :) |
Okay. I'll rebase it this afternoon. |
I think I got the squashing to work. |
There was now 11 commits in the PR, so it seems like after squashing, you pulled from your remote again, solved the unnecessarily conflicts, and thus ended up having the changes done multiple times. So I went ahead and rebased the branch for you. Note that it means your fork's |
@SlashScreen if you want some more interactive support with this, and are interested in participating more in godot I highly recommend the dev chat at https://chat.godotengine.org/ :) |
@akien-mga Whoops! Sorry. I'll do that in the future. I'm not super experienced with branch manipulation. Thanks for fixing that up. @anvilfolk I've spoken in there a few times, and ill be sure to look there if I need help. Although, I think everything is resolved now. |
|
Yeah, there's two commits now - other than that I'd be happy to see this in :) |
Superseeded by: #86999 Thank you for your contribution nonetheless! |
I changed this error message to have a clearer cause ,since this line seems to be caused by godot attempting to initialize a script when the constructor takes more than one argument. Having a clearer message here would have saved me a lot of time.
Changes error message from a terse "Error constructing a GDScriptInstance." to "Error constructing a GDScriptInstance: {error}", where the error matches the error messages given when calling a function improperly in normal GDscript.