Browse Source

Merge pull request #35521 from Calinou/improve-error-macros

Improve and document error macros
Rémi Verschelde 5 years ago
parent
commit
c8d64de766
2 changed files with 199 additions and 115 deletions
  1. 1 1
      core/error_macros.cpp
  2. 198 114
      core/error_macros.h

+ 1 - 1
core/error_macros.cpp

@@ -106,7 +106,7 @@ 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) {
 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) {
 
 
 	String fstr(fatal ? "FATAL: " : "");
 	String fstr(fatal ? "FATAL: " : "");
-	String err(fstr + "Index " + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")");
+	String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
 	_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
 	_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
 }
 }
 
 

+ 198 - 114
core/error_macros.h

@@ -34,8 +34,8 @@
 #include "core/typedefs.h"
 #include "core/typedefs.h"
 /**
 /**
  * Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability
  * 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 stay working well.
+ * 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
  * In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
  * to fail or crash.
  * to fail or crash.
  */
  */
@@ -120,6 +120,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 
 
 // (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
 // (*): 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.
+ */
 #define ERR_FAIL_INDEX(m_index, m_size)                                                                             \
 #define ERR_FAIL_INDEX(m_index, m_size)                                                                             \
 	do {                                                                                                            \
 	do {                                                                                                            \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
@@ -128,6 +133,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                           \
 		}                                                                                                           \
 	} 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)                                                                                    \
 #define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg)                                                                                    \
 	do {                                                                                                                              \
 	do {                                                                                                                              \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
@@ -136,11 +146,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                             \
 		}                                                                                                                             \
 	} while (0); // (*)
 	} while (0); // (*)
 
 
-/** An index has failed if m_index<0 or m_index >=m_size, the function exits.
-* This function returns an error value, if returning Error, please select the most
-* appropriate error condition from error_macros.h
-*/
-
+/**
+ * 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)                                                                 \
 #define ERR_FAIL_INDEX_V(m_index, m_size, m_retval)                                                                 \
 	do {                                                                                                            \
 	do {                                                                                                            \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                     \
@@ -149,6 +159,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                           \
 		}                                                                                                           \
 	} 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)                                                                        \
 #define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg)                                                                        \
 	do {                                                                                                                              \
 	do {                                                                                                                              \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                       \
@@ -157,11 +172,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                             \
 		}                                                                                                                             \
 	} while (0); // (*)
 	} while (0); // (*)
 
 
-/** An index has failed if m_index >=m_size, the function exits.
-* This function returns an error value, if returning Error, please select the most
-* appropriate error condition from error_macros.h
-*/
-
+/**
+ * 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)                                                        \
 #define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval)                                                        \
 	do {                                                                                                            \
 	do {                                                                                                            \
 		if (unlikely((m_index) >= (m_size))) {                                                                      \
 		if (unlikely((m_index) >= (m_size))) {                                                                      \
@@ -170,6 +185,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                           \
 		}                                                                                                           \
 	} 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)                                                               \
 #define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg)                                                               \
 	do {                                                                                                                              \
 	do {                                                                                                                              \
 		if (unlikely((m_index) >= (m_size))) {                                                                                        \
 		if (unlikely((m_index) >= (m_size))) {                                                                                        \
@@ -178,9 +198,12 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                             \
 		}                                                                                                                             \
 	} while (0); // (*)
 	} while (0); // (*)
 
 
-/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
-*   We'll return a null reference and try to keep running.
-*/
+/**
+ * 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)                                                                                      \
 #define CRASH_BAD_INDEX(m_index, m_size)                                                                                      \
 	do {                                                                                                                      \
 	do {                                                                                                                      \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                               \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                               \
@@ -189,6 +212,12 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                     \
 		}                                                                                                                     \
 	} 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)                                                                              \
 #define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg)                                                                              \
 	do {                                                                                                                         \
 	do {                                                                                                                         \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                  \
 		if (unlikely((m_index) < 0 || (m_index) >= (m_size))) {                                                                  \
@@ -197,201 +226,239 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                                                        \
 		}                                                                                                                        \
 	} while (0); // (*)
 	} while (0); // (*)
 
 
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
-  * the function will exit.
-  */
-
+/**
+ * If `m_param` is `null`, prints a generic error message and returns from the function.
+ */
 #define ERR_FAIL_NULL(m_param)                                                                              \
 #define ERR_FAIL_NULL(m_param)                                                                              \
 	{                                                                                                       \
 	{                                                                                                       \
 		if (unlikely(!m_param)) {                                                                           \
 		if (unlikely(!m_param)) {                                                                           \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
 			return;                                                                                         \
 			return;                                                                                         \
 		}                                                                                                   \
 		}                                                                                                   \
 	}
 	}
 
 
+/**
+ * If `m_param` is `null`, prints a custom error message and returns from the function.
+ */
 #define ERR_FAIL_NULL_MSG(m_param, m_msg)                                                                                     \
 #define ERR_FAIL_NULL_MSG(m_param, m_msg)                                                                                     \
 	{                                                                                                                         \
 	{                                                                                                                         \
 		if (unlikely(!m_param)) {                                                                                             \
 		if (unlikely(!m_param)) {                                                                                             \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null.", DEBUG_STR(m_msg)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
 			return;                                                                                                           \
 			return;                                                                                                           \
 		}                                                                                                                     \
 		}                                                                                                                     \
 	}
 	}
 
 
+/**
+ * If `m_param` is `null`, prints a generic error message and returns the value specified in `m_retval`.
+ */
 #define ERR_FAIL_NULL_V(m_param, m_retval)                                                                  \
 #define ERR_FAIL_NULL_V(m_param, m_retval)                                                                  \
 	{                                                                                                       \
 	{                                                                                                       \
 		if (unlikely(!m_param)) {                                                                           \
 		if (unlikely(!m_param)) {                                                                           \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
 			return m_retval;                                                                                \
 			return m_retval;                                                                                \
 		}                                                                                                   \
 		}                                                                                                   \
 	}
 	}
 
 
+/**
+ * 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)                                                                         \
 #define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg)                                                                         \
 	{                                                                                                                         \
 	{                                                                                                                         \
 		if (unlikely(!m_param)) {                                                                                             \
 		if (unlikely(!m_param)) {                                                                                             \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null.", DEBUG_STR(m_msg)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
 			return m_retval;                                                                                                  \
 			return m_retval;                                                                                                  \
 		}                                                                                                                     \
 		}                                                                                                                     \
 	}
 	}
 
 
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
- * the function will exit.
+/**
+ * If `m_cond` evaluates to `true`, prints a generic error message and returns from the function.
  */
  */
-
 #define ERR_FAIL_COND(m_cond)                                                                              \
 #define ERR_FAIL_COND(m_cond)                                                                              \
 	{                                                                                                      \
 	{                                                                                                      \
 		if (unlikely(m_cond)) {                                                                            \
 		if (unlikely(m_cond)) {                                                                            \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true."); \
 			return;                                                                                        \
 			return;                                                                                        \
 		}                                                                                                  \
 		}                                                                                                  \
 	}
 	}
 
 
+/**
+ * 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)                                                                                     \
 #define ERR_FAIL_COND_MSG(m_cond, m_msg)                                                                                     \
 	{                                                                                                                        \
 	{                                                                                                                        \
 		if (unlikely(m_cond)) {                                                                                              \
 		if (unlikely(m_cond)) {                                                                                              \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true.", DEBUG_STR(m_msg)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
 			return;                                                                                                          \
 			return;                                                                                                          \
 		}                                                                                                                    \
 		}                                                                                                                    \
 	}
 	}
 
 
-/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
+/**
+ * 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)                                                                                        \
 #define CRASH_COND(m_cond)                                                                                        \
 	{                                                                                                             \
 	{                                                                                                             \
 		if (unlikely(m_cond)) {                                                                                   \
 		if (unlikely(m_cond)) {                                                                                   \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
 			GENERATE_TRAP                                                                                         \
 			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)                                                                                               \
 #define CRASH_COND_MSG(m_cond, m_msg)                                                                                               \
 	{                                                                                                                               \
 	{                                                                                                                               \
 		if (unlikely(m_cond)) {                                                                                                     \
 		if (unlikely(m_cond)) {                                                                                                     \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true.", DEBUG_STR(m_msg)); \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
 			GENERATE_TRAP                                                                                                           \
 			GENERATE_TRAP                                                                                                           \
 		}                                                                                                                           \
 		}                                                                                                                           \
 	}
 	}
 
 
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
- * the function will exit.
- * This function returns an error value, if returning Error, please select the most
- * appropriate error condition from error_macros.h
+/**
+ * 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)                                                                                            \
 #define ERR_FAIL_COND_V(m_cond, m_retval)                                                                                            \
 	{                                                                                                                                \
 	{                                                                                                                                \
 		if (unlikely(m_cond)) {                                                                                                      \
 		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;                                                                                                         \
 			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)                                                                                                   \
 #define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg)                                                                                                   \
 	{                                                                                                                                                  \
 	{                                                                                                                                                  \
 		if (unlikely(m_cond)) {                                                                                                                        \
 		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;                                                                                                                           \
 			return m_retval;                                                                                                                           \
 		}                                                                                                                                              \
 		}                                                                                                                                              \
 	}
 	}
 
 
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
- * the loop will skip to the next iteration.
- */
-
-#define ERR_CONTINUE(m_cond)                                                                                             \
-	{                                                                                                                    \
-		if (unlikely(m_cond)) {                                                                                          \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \
-			continue;                                                                                                    \
-		}                                                                                                                \
-	}
-
-#define ERR_CONTINUE_MSG(m_cond, m_msg)                                                                                                    \
-	{                                                                                                                                      \
-		if (unlikely(m_cond)) {                                                                                                            \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:", DEBUG_STR(m_msg)); \
-			continue;                                                                                                                      \
-		}                                                                                                                                  \
-	}
-
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
- * the loop will break
+/**
+ * If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
  */
  */
-
-#define ERR_BREAK(m_cond)                                                                                              \
+#define ERR_CONTINUE(m_cond)                                                                                           \
 	{                                                                                                                  \
 	{                                                                                                                  \
 		if (unlikely(m_cond)) {                                                                                        \
 		if (unlikely(m_cond)) {                                                                                        \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
-			break;                                                                                                     \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing."); \
+			continue;                                                                                                  \
 		}                                                                                                              \
 		}                                                                                                              \
 	}
 	}
 
 
-#define ERR_BREAK_MSG(m_cond, m_msg)                                                                                                     \
+/**
+ * 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)) {                                                                                                          \
 		if (unlikely(m_cond)) {                                                                                                          \
-			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:", DEBUG_STR(m_msg)); \
-			break;                                                                                                                       \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", DEBUG_STR(m_msg)); \
+			continue;                                                                                                                    \
 		}                                                                                                                                \
 		}                                                                                                                                \
 	}
 	}
 
 
-/** Print an error string and return
+/**
+ * If `m_cond` evaluates to `true`, prints a generic error message and breaks from the loop the macro is located in.
  */
  */
-
-#define ERR_FAIL()                                                                     \
-	{                                                                                  \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
-		return;                                                                        \
+#define ERR_BREAK(m_cond)                                                                                            \
+	{                                                                                                                \
+		if (unlikely(m_cond)) {                                                                                      \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking."); \
+			break;                                                                                                   \
+		}                                                                                                            \
 	}
 	}
 
 
-#define ERR_FAIL_MSG(m_msg)                                                                              \
-	{                                                                                                    \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed.", DEBUG_STR(m_msg)); \
-		return;                                                                                          \
+/**
+ * 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)) {                                                                                                        \
+			_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", DEBUG_STR(m_msg)); \
+			break;                                                                                                                     \
+		}                                                                                                                              \
 	}
 	}
 
 
-/** Print an error string and return with value
+/**
+ * Prints a generic error message and returns from the function.
  */
  */
-
-#define ERR_FAIL_V(m_value)                                                                                       \
-	{                                                                                                             \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
-		return m_value;                                                                                           \
+#define ERR_FAIL()                                                            \
+	{                                                                         \
+		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed."); \
+		return;                                                               \
 	}
 	}
 
 
-#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 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;                                                                                 \
 	}
 	}
 
 
-/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
+/**
+ * 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;                                                                                  \
+	}
 
 
-#define CRASH_NOW()                                                                           \
-	{                                                                                         \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \
-		GENERATE_TRAP                                                                         \
+/**
+ * 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 CRASH_NOW_MSG(m_msg)                                                                                    \
-	{                                                                                                           \
-		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed.", DEBUG_STR(m_msg)); \
-		GENERATE_TRAP                                                                                           \
+/**
+ * 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                                                                \
 	}
 	}
 
 
-/** Print an error string.
+/**
+ * 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                                                                                  \
+	}
 
 
+/**
+ * Prints an error message without returning.
+ */
 #define ERR_PRINT(m_string)                                           \
 #define ERR_PRINT(m_string)                                           \
 	{                                                                 \
 	{                                                                 \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
 	}
 	}
 
 
+/**
+ * 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)                                          \
 #define ERR_PRINTS(m_string)                                          \
 	{                                                                 \
 	{                                                                 \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
 	}
 	}
 
 
+/**
+ * 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)                                          \
 #define ERR_PRINT_ONCE(m_string)                                          \
 	{                                                                     \
 	{                                                                     \
 		static bool first_print = true;                                   \
 		static bool first_print = true;                                   \
@@ -401,19 +468,28 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                 \
 		}                                                                 \
 	}
 	}
 
 
-/** Print a warning string.
+/**
+ * Prints a warning message without returning. To warn about deprecated usage,
+ * use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
  */
  */
-
 #define WARN_PRINT(m_string)                                                               \
 #define WARN_PRINT(m_string)                                                               \
 	{                                                                                      \
 	{                                                                                      \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, 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)                                                              \
 #define WARN_PRINTS(m_string)                                                              \
 	{                                                                                      \
 	{                                                                                      \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
 		_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, 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)                                                              \
 #define WARN_PRINT_ONCE(m_string)                                                              \
 	{                                                                                          \
 	{                                                                                          \
 		static bool first_print = true;                                                        \
 		static bool first_print = true;                                                        \
@@ -423,22 +499,30 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
 		}                                                                                      \
 		}                                                                                      \
 	}
 	}
 
 
-#define WARN_DEPRECATED                                                                                                                                   \
-	{                                                                                                                                                     \
-		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", ERR_HANDLER_WARNING); \
-			warning_shown = true;                                                                                                                         \
-		}                                                                                                                                                 \
+/**
+ * Prints a generic deprecation warning message without returning.
+ * This should be preferred to `WARN_PRINT` for deprecation warnings.
+ */
+#define WARN_DEPRECATED                                                                                                                                    \
+	{                                                                                                                                                      \
+		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.", 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", m_msg, ERR_HANDLER_WARNING); \
-			warning_shown = true;                                                                                                                                \
-		}                                                                                                                                                        \
+/**
+ * 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;                                                                                                                                 \
+		}                                                                                                                                                         \
 	}
 	}
 
 
 #endif
 #endif