mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 17:49:40 +00:00
AK: Print a more useful error message when a MUST(...)
fails
``` VERIFICATION FAILED: !_temporary_result.is_error() ``` is not really a helpful error message. When we are including `AK/Format.h`, which is most of the time, we can easily print a much more useful error message: ``` UNEXPECTED ERROR: Cannot allocate memory (errno=12) ```
This commit is contained in:
parent
0afd7f166a
commit
e38b206957
Notes:
github-actions[bot]
2024-12-02 19:08:30 +00:00
Author: https://github.com/yyny
Commit: e38b206957
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2660
4 changed files with 41 additions and 23 deletions
|
@ -81,45 +81,42 @@ ALWAYS_INLINE void dump_backtrace()
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void ak_verification_failed(char const* message)
|
bool ak_colorize_output(void)
|
||||||
{
|
{
|
||||||
#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID)
|
#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID)
|
||||||
bool colorize_output = true;
|
return true;
|
||||||
#elif defined(AK_OS_WINDOWS)
|
#elif defined(AK_OS_WINDOWS)
|
||||||
bool colorize_output = false;
|
return false;
|
||||||
#else
|
#else
|
||||||
bool colorize_output = isatty(STDERR_FILENO) == 1;
|
return isatty(STDERR_FILENO) == 1;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (colorize_output)
|
void ak_trap(void)
|
||||||
|
{
|
||||||
|
#if defined(AK_HAS_BACKTRACE_HEADER)
|
||||||
|
dump_backtrace();
|
||||||
|
#endif
|
||||||
|
__builtin_trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ak_verification_failed(char const* message)
|
||||||
|
{
|
||||||
|
if (ak_colorize_output())
|
||||||
ERRORLN("\033[31;1mVERIFICATION FAILED\033[0m: {}", message);
|
ERRORLN("\033[31;1mVERIFICATION FAILED\033[0m: {}", message);
|
||||||
else
|
else
|
||||||
ERRORLN("VERIFICATION FAILED: {}", message);
|
ERRORLN("VERIFICATION FAILED: {}", message);
|
||||||
|
|
||||||
#if defined(AK_HAS_BACKTRACE_HEADER)
|
ak_trap();
|
||||||
dump_backtrace();
|
|
||||||
#endif
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ak_assertion_failed(char const* message)
|
void ak_assertion_failed(char const* message)
|
||||||
{
|
{
|
||||||
#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID)
|
if (ak_colorize_output())
|
||||||
bool colorize_output = true;
|
|
||||||
#elif defined(AK_OS_WINDOWS)
|
|
||||||
bool colorize_output = false;
|
|
||||||
#else
|
|
||||||
bool colorize_output = isatty(STDERR_FILENO) == 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (colorize_output)
|
|
||||||
ERRORLN("\033[31;1mASSERTION FAILED\033[0m: {}", message);
|
ERRORLN("\033[31;1mASSERTION FAILED\033[0m: {}", message);
|
||||||
else
|
else
|
||||||
ERRORLN("ASSERTION FAILED: {}", message);
|
ERRORLN("ASSERTION FAILED: {}", message);
|
||||||
|
|
||||||
#if defined(AK_HAS_BACKTRACE_HEADER)
|
ak_trap();
|
||||||
dump_backtrace();
|
|
||||||
#endif
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
extern "C" bool ak_colorize_output(void);
|
||||||
|
extern "C" __attribute__((noreturn)) void ak_trap(void);
|
||||||
|
|
||||||
extern "C" __attribute__((noreturn)) void ak_verification_failed(char const*);
|
extern "C" __attribute__((noreturn)) void ak_verification_failed(char const*);
|
||||||
#define __stringify_helper(x) #x
|
#define __stringify_helper(x) #x
|
||||||
#define __stringify(x) __stringify_helper(x)
|
#define __stringify(x) __stringify_helper(x)
|
||||||
|
|
15
AK/Format.h
15
AK/Format.h
|
@ -775,6 +775,21 @@ struct Formatter<Optional<T>> : Formatter<FormatString> {
|
||||||
|
|
||||||
} // namespace AK
|
} // namespace AK
|
||||||
|
|
||||||
|
#undef AK_HANDLE_UNEXPECTED_ERROR
|
||||||
|
#define AK_HANDLE_UNEXPECTED_ERROR(result) \
|
||||||
|
if (result.is_error()) [[unlikely]] { \
|
||||||
|
if (ak_colorize_output()) { \
|
||||||
|
::AK::warn("\033[31;1mUNEXPECTED ERROR\033[0m"); \
|
||||||
|
} else { \
|
||||||
|
::AK::warn("UNEXPECTED ERROR"); \
|
||||||
|
} \
|
||||||
|
if constexpr (::AK::HasFormatter<decltype(result.release_error())>) { \
|
||||||
|
::AK::warn(": {}", result.release_error()); \
|
||||||
|
} \
|
||||||
|
::AK::warnln(" at {}:{}", __FILE__, __LINE__); \
|
||||||
|
ak_trap(); \
|
||||||
|
}
|
||||||
|
|
||||||
#if USING_AK_GLOBALLY
|
#if USING_AK_GLOBALLY
|
||||||
using AK::out;
|
using AK::out;
|
||||||
using AK::outln;
|
using AK::outln;
|
||||||
|
|
5
AK/Try.h
5
AK/Try.h
|
@ -9,6 +9,9 @@
|
||||||
#include <AK/Diagnostics.h>
|
#include <AK/Diagnostics.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
|
||||||
|
// This macro is redefined in `AK/Format.h` to give a nicer error message.
|
||||||
|
#define AK_HANDLE_UNEXPECTED_ERROR(result) VERIFY(!result.is_error());
|
||||||
|
|
||||||
// NOTE: This macro works with any result type that has the expected APIs.
|
// NOTE: This macro works with any result type that has the expected APIs.
|
||||||
// It's designed with AK::Result and AK::Error in mind.
|
// It's designed with AK::Result and AK::Error in mind.
|
||||||
//
|
//
|
||||||
|
@ -40,6 +43,6 @@
|
||||||
auto&& _temporary_result = (expression)); \
|
auto&& _temporary_result = (expression)); \
|
||||||
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \
|
||||||
"Do not return a reference from a fallible expression"); \
|
"Do not return a reference from a fallible expression"); \
|
||||||
VERIFY(!_temporary_result.is_error()); \
|
AK_HANDLE_UNEXPECTED_ERROR(_temporary_result) \
|
||||||
_temporary_result.release_value(); \
|
_temporary_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue