Currently there's no way to display custom error message in assert call. It would be great for debugging, and establishing invariants in published libraries if we could optionally customize what assert displays. Example:

AFAIK most modern engines and programming languages have message handling in assertion macros/functions.
Taking a stab in the dark but didn't get very far:
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index f006d50a8..a5ad29fea 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3274,14 +3274,29 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
return;
}
+
AssertNode *an = alloc_node<AssertNode>();
an->condition = condition;
p_block->statements.push_back(an);
+ if (_end_statement()) {
+ // The only argument was the expression.
+ return;
+ }
- if (!_end_statement()) {
- _set_error("Expected end of statement after assert.");
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
+ Node *message_expression = _parse_and_reduce_expression(p_block, p_static);
+ if (!message_expression) {
+ if (_recover_from_completion()) {
+ break;
+ }
+ return;
+ }
+ an->message = message_expression;
return;
}
+
+ _set_error("Expected end of statement after assert.");
+ return;
} break;
case GDScriptTokenizer::TK_PR_BREAKPOINT: {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 62d7bdb39..832376b09 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -481,6 +481,7 @@ public:
struct AssertNode : public Node {
Node *condition;
+ Node *message;
AssertNode() { type = TYPE_ASSERT; }
};
I assume I need to somehow parse the message expression here:
https://github.com/godotengine/godot/blob/master/modules/gdscript/gdscript_compiler.cpp#L1515
Something like:
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 4c976bd2e..7825be1c5 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1522,7 +1522,12 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
if (ret2 < 0)
return ERR_PARSE_ERROR;
+ int message_ret = _parse_expression(codegen, as->message, p_stack_level, false);
+ if (message_ret < 0)
+ return ERR_PARSE_ERROR;
+
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
+ // ???
codegen.opcodes.push_back(ret2);
#endif
} break;
But I don't know how printing a message translates to these opcodes. I guess it involves something like this:
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 42f349ffc..14ad43940 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1482,8 +1482,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool result = test->booleanize();
if (!result) {
-
- err_text = "Assertion failed.";
+ GET_VARIANT_PTR(message, 2);
+ if (!message) {
+ err_text = "Assertion failed.";
+ } else {
+ err_text = "Assertion failed: " + message;
+ }
OPCODE_BREAK;
}
or maybe it's not possible to do it this way, and there has to be a new assert function (e.g. assert_message()).
@bojidar-bg, @reduz: any tips?
Back when I initially posted this suggestion I created a crude proof of concept.
Here's the commit: https://github.com/wiped1/godot/commit/3db71c3dbf887bc9622b90d056765d4dd688ed58
It appears to be working, and has lots of similarities with your concept. You may want to look at my take on opcode generation (basically copied from how ret2 was parsed).
Note: There may be lots of rebase errors, because I haven't looked at this since 2018.
Thanks!
Thanks to your patch, @wiped1, I got this far last night:
https://github.com/mitchcurtis/godot/commit/d1ddf07751948f1080b3db21831a1dc8ae93423f
The parsing and compiling seem to go smoothly from what I can see while debugging, but the OPCODE_ASSERT code in gdscript_function.cpp is not hit at all. I'm using this minimal code as a test:
extends Node2D
func _init():
print("uh-oh ", OS.is_debug_build())
# assert(false)
assert(1 == 2, "boop")
Any tips for debugging this?
Try out the suggestion I wrote in your commit.
Also I believe someone should review gdscript_praser.cpp, I don't trust my year-old code there 馃槃
Most helpful comment
Back when I initially posted this suggestion I created a crude proof of concept.
Here's the commit: https://github.com/wiped1/godot/commit/3db71c3dbf887bc9622b90d056765d4dd688ed58
It appears to be working, and has lots of similarities with your concept. You may want to look at my take on opcode generation (basically copied from how
ret2was parsed).Note: There may be lots of rebase errors, because I haven't looked at this since 2018.