2
0
Marcel Admiraal 5 жил өмнө
parent
commit
2b1084fab3
1 өөрчлөгдсөн 201 нэмэгдсэн , 258 устгасан
  1. 201 258
      core/error_macros.h

+ 201 - 258
core/error_macros.h

@@ -32,21 +32,8 @@
 #define ERROR_MACROS_H
 
 #include "core/typedefs.h"
-/**
- * Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability
- * inside the code. It is recommended to always return processable data, so in case of an error,
- * the engine can keep working well.
- * In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
- * to fail or crash.
- */
-
-/**
- * Pointer to the error macro printing function. Reassign to any function to have errors printed
- */
-
-/** Function used by the error macros */
 
-// function, file, line, error, explanation
+class String;
 
 enum ErrorHandlerType {
 	ERR_HANDLER_ERROR,
@@ -55,7 +42,8 @@ enum ErrorHandlerType {
 	ERR_HANDLER_SHADER,
 };
 
-class String;
+// Pointer to the error handler printing function. Reassign to any function to have errors printed.
+// Parameters: userdata, function, file, line, error, explanation, type.
 typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
 
 struct ErrorHandlerList {
@@ -75,6 +63,7 @@ struct ErrorHandlerList {
 void add_error_handler(ErrorHandlerList *p_handler);
 void remove_error_handler(ErrorHandlerList *p_handler);
 
+// Functions used by the error macros.
 void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
 void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
 void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
@@ -84,15 +73,6 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
 void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false);
 void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
 
-#ifndef _STR
-#define _STR(m_x) #m_x
-#define _MKSTR(m_x) _STR(m_x)
-#endif
-
-#define _FNL __FILE__ ":"
-
-/** An index has failed if m_index<0 or m_index >=m_size, the function exits */
-
 #ifdef __GNUC__
 //#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying
 #define FUNCTION_STR __FUNCTION__
@@ -102,13 +82,9 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 
 // Don't use this directly; instead, use any of the CRASH_* macros
 #ifdef _MSC_VER
-#define GENERATE_TRAP                       \
-	__debugbreak();                         \
-	/* Avoid warning about control paths */ \
-	for (;;) {                              \
-	}
+#define GENERATE_TRAP() __debugbreak()
 #else
-#define GENERATE_TRAP __builtin_trap();
+#define GENERATE_TRAP() __builtin_trap()
 #endif
 
 // Used to strip debug messages in release mode
@@ -118,117 +94,141 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 #define DEBUG_STR(m_msg) ""
 #endif
 
-// (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
-
 /**
- * If `m_index` is less than 0 or greater than or equal to `m_size`, prints a generic
- * error message and returns from the function. This macro should be preferred to
- * `ERR_FAIL_COND` for bounds checking.
+ * Error macros.
+ * WARNING: These macros work in the opposite way to assert().
+ *
+ * Unlike exceptions and asserts, these macros try to maintain consistency and stability.
+ * In most cases, bugs and/or invalid data are not fatal. They should never allow a perfectly
+ * running application to fail or crash.
+ * 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: See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
  */
+
+// Index out of bounds error macros.
+// These macros should be used instead of `ERR_FAIL_COND` for bounds checking.
+
+// Integer index out of bounds error macros.
+// Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
+
+// The current function returns.
+
 #define ERR_FAIL_INDEX(m_index, m_size)                                                                             \
 	do {                                                                                                            \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
 			return;                                                                                                 \
 		}                                                                                                           \
-	} while (0); // (*)
+	} while (0);
 
-/**
- * If `m_index` is less than 0 or greater than or equal to `m_size`, prints a custom
- * error message and returns from the function. This macro should be preferred to
- * `ERR_FAIL_COND_MSG` for bounds checking.
- */
 #define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg)                                                                                    \
 	do {                                                                                                                              \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
 			return;                                                                                                                   \
 		}                                                                                                                             \
-	} while (0); // (*)
+	} while (0);
+
+// The current function returns m_retval.
 
-/**
- * If `m_index` is less than 0 or greater than or equal to `m_size`,
- * prints a generic error message and returns the value specified in `m_retval`.
- * This macro should be preferred to `ERR_FAIL_COND_V` for bounds checking.
- */
 #define ERR_FAIL_INDEX_V(m_index, m_size, m_retval)                                                                 \
 	do {                                                                                                            \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
 			return m_retval;                                                                                        \
 		}                                                                                                           \
-	} while (0); // (*)
+	} while (0);
 
-/**
- * If `m_index` is less than 0 or greater than or equal to `m_size`,
- * prints a custom error message and returns the value specified in `m_retval`.
- * This macro should be preferred to `ERR_FAIL_COND_V_MSG` for bounds checking.
- */
 #define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg)                                                                        \
 	do {                                                                                                                              \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
 			return m_retval;                                                                                                          \
 		}                                                                                                                             \
-	} while (0); // (*)
+	} while (0);
+
+// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
+
+#define CRASH_BAD_INDEX(m_index, m_size)                                                                                      \
+	do {                                                                                                                      \
+		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                               \
+			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
+			GENERATE_TRAP();                                                                                                  \
+		}                                                                                                                     \
+	} while (0);
+
+#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg)                                                                                         \
+	do {                                                                                                                                    \
+		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                             \
+			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \
+			GENERATE_TRAP();                                                                                                                \
+		}                                                                                                                                   \
+	} while (0);
+
+// Unsigned integer index out of bounds error macros.
+// Ensures an unsigned integer index `m_index` is less than `m_size`
+
+// The current function returns.
+
+#define ERR_FAIL_UNSIGNED_INDEX(m_index, m_size)                                                                    \
+	do {                                                                                                            \
+		if (unlikely((m_index) >= (m_size))) {                                                                      \
+			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+			return;                                                                                                 \
+		}                                                                                                           \
+	} while (0);
+
+#define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg)                                                                           \
+	do {                                                                                                                              \
+		if (unlikely((m_index) >= (m_size))) {                                                                                        \
+			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
+			return;                                                                                                                   \
+		}                                                                                                                             \
+	} while (0);
+
+// The current function returns m_retval.
 
-/**
- * If `m_index` is greater than or equal to `m_size`,
- * prints a generic error message and returns the value specified in `m_retval`.
- * This macro should be preferred to `ERR_FAIL_COND_V` for unsigned bounds checking.
- */
 #define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval)                                                        \
 	do {                                                                                                            \
 		if (unlikely((m_index) >= (m_size))) {                                                                      \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
 			return m_retval;                                                                                        \
 		}                                                                                                           \
-	} while (0); // (*)
+	} while (0);
 
-/**
- * If `m_index` is greater than or equal to `m_size`,
- * prints a custom error message and returns the value specified in `m_retval`.
- * This macro should be preferred to `ERR_FAIL_COND_V_MSG` for unsigned bounds checking.
- */
 #define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg)                                                               \
 	do {                                                                                                                              \
 		if (unlikely((m_index) >= (m_size))) {                                                                                        \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
 			return m_retval;                                                                                                          \
 		}                                                                                                                             \
-	} while (0); // (*)
+	} while (0);
 
-/**
- * If `m_index` is less than 0 or greater than or equal to `m_size`,
- * crashes the engine immediately with a generic error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- * This macro should be preferred to `CRASH_COND` for bounds checking.
- */
-#define CRASH_BAD_INDEX(m_index, m_size)                                                                                      \
+// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
+
+#define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size)                                                                             \
 	do {                                                                                                                      \
-		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                               \
+		if (unlikely((m_index) >= (m_size))) {                                                                                \
 			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
-			GENERATE_TRAP                                                                                                     \
+			GENERATE_TRAP();                                                                                                  \
 		}                                                                                                                     \
-	} while (0); // (*)
+	} while (0);
 
-/**
- * If `m_index` is less than 0 or greater than or equal to `m_size`,
- * crashes the engine immediately with a custom error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- * This macro should be preferred to `CRASH_COND` for bounds checking.
- */
-#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg)                                                                              \
-	do {                                                                                                                         \
-		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                  \
-			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
-			GENERATE_TRAP                                                                                                        \
-		}                                                                                                                        \
-	} while (0); // (*)
+#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg)                                                                                \
+	do {                                                                                                                                    \
+		if (unlikely((m_index) >= (m_size))) {                                                                                              \
+			_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \
+			GENERATE_TRAP();                                                                                                                \
+		}                                                                                                                                   \
+	} while (0);
+
+// Null reference error macros.
+// Ensures a pointer `m_param` is not null.
+
+// The current function returns.
 
-/**
- * If `m_param` is `null`, prints a generic error message and returns from the function.
- */
 #define ERR_FAIL_NULL(m_param)                                                                              \
 	{                                                                                                       \
 		if (unlikely(!m_param)) {                                                                           \
@@ -237,9 +237,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                   \
 	}
 
-/**
- * If `m_param` is `null`, prints a custom error message and returns from the function.
- */
 #define ERR_FAIL_NULL_MSG(m_param, m_msg)                                                                                     \
 	{                                                                                                                         \
 		if (unlikely(!m_param)) {                                                                                             \
@@ -248,9 +245,8 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                     \
 	}
 
-/**
- * If `m_param` is `null`, prints a generic error message and returns the value specified in `m_retval`.
- */
+// The current function returns m_retval.
+
 #define ERR_FAIL_NULL_V(m_param, m_retval)                                                                  \
 	{                                                                                                       \
 		if (unlikely(!m_param)) {                                                                           \
@@ -259,9 +255,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                   \
 	}
 
-/**
- * If `m_param` is `null`, prints a custom error message and returns the value specified in `m_retval`.
- */
 #define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg)                                                                         \
 	{                                                                                                                         \
 		if (unlikely(!m_param)) {                                                                                             \
@@ -270,9 +263,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                     \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a generic error message and returns from the function.
- */
+// Error condition macros.
+// Ensures that `m_cond` is not true.
+
+// The current function returns.
+
 #define ERR_FAIL_COND(m_cond)                                                                              \
 	{                                                                                                      \
 		if (unlikely(m_cond)) {                                                                            \
@@ -281,9 +276,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                  \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a custom error message and returns from the function.
- */
 #define ERR_FAIL_COND_MSG(m_cond, m_msg)                                                                                     \
 	{                                                                                                                        \
 		if (unlikely(m_cond)) {                                                                                              \
@@ -292,55 +284,26 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                    \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, crashes the engine immediately with a generic error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- */
-#define CRASH_COND(m_cond)                                                                                        \
-	{                                                                                                             \
-		if (unlikely(m_cond)) {                                                                                   \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
-			GENERATE_TRAP                                                                                         \
-		}                                                                                                         \
-	}
-
-/**
- * If `m_cond` evaluates to `true`, crashes the engine immediately with a custom error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- */
-#define CRASH_COND_MSG(m_cond, m_msg)                                                                                               \
-	{                                                                                                                               \
-		if (unlikely(m_cond)) {                                                                                                     \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
-			GENERATE_TRAP                                                                                                           \
-		}                                                                                                                           \
-	}
+// The current function returns m_retval.
 
-/**
- * If `m_cond` evaluates to `true`, prints a generic error message and returns the value specified in `m_retval`.
- */
 #define ERR_FAIL_COND_V(m_cond, m_retval)                                                                                            \
 	{                                                                                                                                \
 		if (unlikely(m_cond)) {                                                                                                      \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. returned: " _STR(m_retval)); \
 			return m_retval;                                                                                                         \
 		}                                                                                                                            \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a custom error message and returns the value specified in `m_retval`.
- */
 #define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg)                                                                                                   \
 	{                                                                                                                                                  \
 		if (unlikely(m_cond)) {                                                                                                                        \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval), DEBUG_STR(m_msg)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. returned: " _STR(m_retval), DEBUG_STR(m_msg)); \
 			return m_retval;                                                                                                                           \
 		}                                                                                                                                              \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
- */
+// The current loop continues.
+
 #define ERR_CONTINUE(m_cond)                                                                                           \
 	{                                                                                                                  \
 		if (unlikely(m_cond)) {                                                                                        \
@@ -349,9 +312,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                              \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
- */
 #define ERR_CONTINUE_MSG(m_cond, m_msg)                                                                                                  \
 	{                                                                                                                                    \
 		if (unlikely(m_cond)) {                                                                                                          \
@@ -360,9 +320,8 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                                \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a generic error message and breaks from the loop the macro is located in.
- */
+// The current loop breaks.
+
 #define ERR_BREAK(m_cond)                                                                                            \
 	{                                                                                                                \
 		if (unlikely(m_cond)) {                                                                                      \
@@ -371,9 +330,6 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                            \
 	}
 
-/**
- * If `m_cond` evaluates to `true`, prints a custom error message and breaks from the loop the macro is located in.
- */
 #define ERR_BREAK_MSG(m_cond, m_msg)                                                                                                   \
 	{                                                                                                                                  \
 		if (unlikely(m_cond)) {                                                                                                        \
@@ -382,127 +338,104 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                              \
 	}
 
-/**
- * Prints a generic error message and returns from the function.
- */
-#define ERR_FAIL()                                                            \
-	{                                                                         \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed."); \
-		return;                                                               \
+// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
+
+#define CRASH_COND(m_cond)                                                                                        \
+	{                                                                                                             \
+		if (unlikely(m_cond)) {                                                                                   \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
+			GENERATE_TRAP();                                                                                      \
+		}                                                                                                         \
 	}
 
-/**
- * Prints a custom error message and returns from the function.
- */
-#define ERR_FAIL_MSG(m_msg)                                                                     \
-	{                                                                                           \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed.", DEBUG_STR(m_msg)); \
-		return;                                                                                 \
+#define CRASH_COND_MSG(m_cond, m_msg)                                                                                               \
+	{                                                                                                                               \
+		if (unlikely(m_cond)) {                                                                                                     \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
+			GENERATE_TRAP();                                                                                                        \
+		}                                                                                                                           \
 	}
 
-/**
- * Prints a generic error message and returns the value specified in `m_retval`.
- */
-#define ERR_FAIL_V(m_retval)                                                                              \
-	{                                                                                                     \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval)); \
-		return m_retval;                                                                                  \
+// Generic error macros.
+
+// The current function returns.
+
+#define ERR_FAIL()                                                                     \
+	{                                                                                  \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
+		return;                                                                        \
 	}
 
-/**
- * Prints a custom error message and returns the value specified in `m_retval`.
- */
-#define ERR_FAIL_V_MSG(m_retval, m_msg)                                                                                     \
-	{                                                                                                                       \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval), DEBUG_STR(m_msg)); \
-		return m_retval;                                                                                                    \
+#define ERR_FAIL_MSG(m_msg)                                                                              \
+	{                                                                                                    \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed.", DEBUG_STR(m_msg)); \
+		return;                                                                                          \
 	}
 
-/**
- * Crashes the engine immediately with a generic error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- */
-#define CRASH_NOW()                                                                  \
-	{                                                                                \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed."); \
-		GENERATE_TRAP                                                                \
+// The current function returns m_retval.
+
+#define ERR_FAIL_V(m_retval)                                                                                      \
+	{                                                                                                             \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
+		return m_retval;                                                                                          \
 	}
 
-/**
- * Crashes the engine immediately with a custom error message.
- * Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
- */
-#define CRASH_NOW_MSG(m_msg)                                                                           \
-	{                                                                                                  \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed.", DEBUG_STR(m_msg)); \
-		GENERATE_TRAP                                                                                  \
+#define ERR_FAIL_V_MSG(m_value, m_msg)                                                                                              \
+	{                                                                                                                               \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value), DEBUG_STR(m_msg)); \
+		return m_value;                                                                                                             \
 	}
 
-/**
- * Prints an error message without returning.
- */
-#define ERR_PRINT(m_string)                                           \
-	{                                                                 \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
+// Print error message macros.
+
+#define ERR_PRINT(m_msg)                                                      \
+	{                                                                         \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg)); \
 	}
 
-/**
- * Prints an error message without returning.
- * FIXME: Remove this macro and replace all uses with `ERR_PRINT` as it's identical.
- */
-#define ERR_PRINTS(m_string)                                          \
-	{                                                                 \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
+#define ERR_PRINTS(m_msg)                                                     \
+	{                                                                         \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg)); \
 	}
 
-/**
- * Prints an error message without returning, but only do so once in the application lifecycle.
- * This can be used to avoid spamming the console with error messages.
- */
-#define ERR_PRINT_ONCE(m_string)                                          \
-	{                                                                     \
-		static bool first_print = true;                                   \
-		if (first_print) {                                                \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
-			first_print = false;                                          \
-		}                                                                 \
+// Only prints the error message once.
+
+#define ERR_PRINT_ONCE(m_msg)                                                     \
+	{                                                                             \
+		static bool first_print = true;                                           \
+		if (first_print) {                                                        \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg)); \
+			first_print = false;                                                  \
+		}                                                                         \
 	}
 
-/**
- * Prints a warning message without returning. To warn about deprecated usage,
- * use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
- */
-#define WARN_PRINT(m_string)                                                               \
-	{                                                                                      \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
+// Print warning message macros.
+// To warn about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
+
+#define WARN_PRINT(m_msg)                                                                          \
+	{                                                                                              \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
 	}
 
-/**
- * Prints a warning message without returning.
- * FIXME: Remove this macro and replace all uses with `WARN_PRINT` as it's identical.
- */
-#define WARN_PRINTS(m_string)                                                              \
-	{                                                                                      \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
+#define WARN_PRINTS(m_msg)                                                                         \
+	{                                                                                              \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
 	}
 
-/**
- * Prints a warning message without returning, but only do so once in the application lifecycle.
- * This can be used to avoid spamming the console with warning messages.
- */
-#define WARN_PRINT_ONCE(m_string)                                                              \
-	{                                                                                          \
-		static bool first_print = true;                                                        \
-		if (first_print) {                                                                     \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
-			first_print = false;                                                               \
-		}                                                                                      \
+// Only prints the warning message once.
+
+#define WARN_PRINT_ONCE(m_msg)                                                                         \
+	{                                                                                                  \
+		static bool first_print = true;                                                                \
+		if (first_print) {                                                                             \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
+			first_print = false;                                                                       \
+		}                                                                                              \
 	}
 
-/**
- * Prints a generic deprecation warning message without returning.
- * This should be preferred to `WARN_PRINT` for deprecation warnings.
- */
+// Print deprecated warning message macros.
+// Only prints the warning message once.
+
 #define WARN_DEPRECATED                                                                                                                                    \
 	{                                                                                                                                                      \
 		static volatile bool warning_shown = false;                                                                                                        \
@@ -512,17 +445,27 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                                                  \
 	}
 
-/**
- * Prints a custom deprecation warning message without returning.
- * This should be preferred to `WARN_PRINT` for deprecation warnings.
- */
-#define WARN_DEPRECATED_MSG(m_msg)                                                                                                                                \
-	{                                                                                                                                                             \
-		static volatile bool warning_shown = false;                                                                                                               \
-		if (!warning_shown) {                                                                                                                                     \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \
-			warning_shown = true;                                                                                                                                 \
-		}                                                                                                                                                         \
+#define WARN_DEPRECATED_MSG(m_msg)                                                                                                                                           \
+	{                                                                                                                                                                        \
+		static volatile bool warning_shown = false;                                                                                                                          \
+		if (!warning_shown) {                                                                                                                                                \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
+			warning_shown = true;                                                                                                                                            \
+		}                                                                                                                                                                    \
+	}
+
+// Only use CRASH macros if there is no sensible fallback, that is, the error is unrecoverable.
+
+#define CRASH_NOW()                                                                           \
+	{                                                                                         \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \
+		GENERATE_TRAP();                                                                      \
+	}
+
+#define CRASH_NOW_MSG(m_msg)                                                                                    \
+	{                                                                                                           \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed.", DEBUG_STR(m_msg)); \
+		GENERATE_TRAP();                                                                                        \
 	}
 
 #endif