Skip to content
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

De-duplicate error spam. #84724

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/error/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ Import("env")

env_error = env.Clone()

if env["tests"]:
env_error.Append(CPPDEFINES=["TESTS_ENABLED"])

env_error.add_source_files(env.core_sources, "*.cpp")
23 changes: 23 additions & 0 deletions core/error/error_macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,29 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co

// Main error printing function.
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
#ifndef TESTS_ENABLED
_global_lock();
// Eliminate duplicate errors to stop locking up the editor due to spam.
static int prev_line = INT_MAX;
static uint32_t prev_frame = UINT32_MAX;
static CharString prev_function;
static CharString prev_file;
static CharString prev_error;

// Only de-duplicate on the current frame.
uint32_t curr_frame = Engine::get_singleton()->get_process_frames();
if ((prev_frame == curr_frame) && (prev_line == p_line) && (prev_function == p_function) && (prev_file == p_file) && (prev_error == p_error)) {
_global_unlock();
return;
}
prev_function = p_function;
prev_file = p_file;
prev_line = p_line;
prev_error = p_error;
prev_frame = curr_frame;
_global_unlock();
#endif

if (OS::get_singleton()) {
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, p_editor_notify, (Logger::ErrorType)p_type);
} else {
Expand Down
4 changes: 4 additions & 0 deletions core/error/error_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ void _err_flush_stdout();
* Always try to return processable data, so the engine can keep running well.
* Use the _MSG versions to print a meaningful message to help with debugging.
*
* NOTE: Error and warning messages are deduplicated on a per-frame basis, to prevent
* spam. If you wish to output multiple similar errors / warnings, be sure to differentiate them.
* See _err_print_error().
*
* The `((void)0)` no-op statement is used as a trick to force us to put a semicolon after
* those macros, making them look like proper statements.
* The if wrappers are used to ensure that the macro replacement does not trigger unexpected
Expand Down
10 changes: 10 additions & 0 deletions core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ bool CharString::operator<(const CharString &p_right) const {
return is_str_less(get_data(), p_right.get_data());
}

bool CharString::operator==(const char *p_right) const {
// nullptr and null terminator translate to the same CharString, length 0.
if (p_right == nullptr || p_right[0] == 0) {
return length() == 0;
} else if (length() == 0) {
return false;
}
return strcmp(ptr(), p_right) == 0;
}

bool CharString::operator==(const CharString &p_right) const {
if (length() == 0) {
// True if both have length 0, false if only p_right has a length
Expand Down
1 change: 1 addition & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class CharString {
void operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
bool operator==(const CharString &p_right) const;
bool operator==(const char *p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
Expand Down