Ladybird avoids C-style error codes and exceptions in favour of a consistent, value-based error-handling model built around theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ladybirdBrowser/ladybird/llms.txt
Use this file to discover all available pages before exploring further.
ErrorOr<T> return type. Two macros — TRY and MUST — dramatically reduce the boilerplate required to
propagate errors through a call stack. Alongside these, a set of custom smart pointer types makes ownership explicit
in every function signature and eliminates entire classes of memory bugs.
Error Handling with TRY and MUST
TRY(…)
TheTRY(...) macro is the primary mechanism for propagating errors in Ladybird. Any expression wrapped in TRY is
evaluated; if it returns an error, that error is immediately returned from the enclosing function. If it succeeds, the
unwrapped value becomes the result of the macro expression.
This is conceptually similar to the ? operator in Rust.
Example from LibGfx:
Core::AnonymousBuffer::create_with_size and Bitmap::create_with_anonymous_buffer return ErrorOr<...>. If
either fails, the error is returned immediately without any explicit if-checking.
MUST(…)
MUST(...) is similar to TRY, except that instead of propagating an error it asserts (crashes the program) if
the wrapped expression fails. Use it only when you have determined through other logic that the operation genuinely
cannot fail, or when a failure would be severe enough to warrant an immediate abort.
MUST(...) is not a substitute for TRY(...) in places where error propagation is merely inconvenient. When
you cannot propagate errors right now but the call site should eventually do so, use
release_value_but_fixme_should_propagate_errors() on the ErrorOr<> instead. This marks the location for future
improvement without silently swallowing errors.Fallible Constructors
Standard C++ constructors cannot return anErrorOr<T>, which means they cannot participate in the TRY-based error
propagation model. Classes that need to perform fallible operations during construction use a static factory function
(conventionally named create) instead.
The create function handles all fallible pre-construction work, constructs the object via a private constructor, runs
any fallible post-construction steps, and returns the completed object as ErrorOr<T> or
ErrorOr<NonnullOwnPtr<T>>.
Smart Pointers
Ladybird’s AK library provides three smart pointer types. Each one makes ownership semantics explicit in the type itself, guards against memory leaks, and prevents use-after-free bugs.OwnPtr<T> and NonnullOwnPtr<T> — Single Owner
OwnPtr<T> and NonnullOwnPtr<T> — Single Owner
OwnPtr<T> represents single ownership: exactly one OwnPtr owns the pointee, and the pointee is deleted when
that OwnPtr goes out of scope. These pointers are move-only — they cannot be copied.NonnullOwnPtr<T> is a variant of OwnPtr that cannot hold null. It is appropriate as a return type for functions
that are guaranteed to return a valid object, and as a parameter type when ownership is transferred and null is not
permitted.A NonnullOwnPtr can be assigned to an OwnPtr, but not vice versa. To promote a known-non-null OwnPtr to
NonnullOwnPtr, call OwnPtr::release_nonnull().Preferred construction — helper functions:RefPtr<T> and NonnullRefPtr<T> — Shared Ownership
RefPtr<T> and NonnullRefPtr<T> — Shared Ownership
WeakPtr<T> — Non-Owning Weak Reference
WeakPtr<T> — Non-Owning Weak Reference
WeakPtr<T> holds a non-owning reference to an object. When the pointee is destroyed, the WeakPtr
automatically becomes null — making it safe to hold a reference to an object without extending its lifetime.To allow a class to be weakly pointed to, inherit from Weakable<T> and call make_weak_ptr() to create a
WeakPtr:Choosing the Right Pointer Type
| Situation | Pointer type |
|---|---|
| One clear owner; object should be deleted when owner goes away | OwnPtr<T> / NonnullOwnPtr<T> |
| Multiple owners that share lifetime of the object | RefPtr<T> / NonnullRefPtr<T> |
| You need to observe an object without keeping it alive | WeakPtr<T> |
| Return from a function guaranteed not to return null | NonnullOwnPtr<T> or NonnullRefPtr<T> |
Other Notable Patterns
ladybird_main Entry Point
Ladybird executables exposeladybird_main(Main::Arguments) instead of a standard int main(int, char**). The
Main::Arguments struct provides arguments idiomatically, and the ErrorOr<int> return type allows seamless error
propagation via TRY from the very top of the program. The LibMain library provides the standard main entry point
that calls into ladybird_main.
String View Literals
AK::StringView supports the ""sv literal operator, allowing string views to be constructed from literals at zero
runtime cost (the length is computed at compile time and the data lives in the binary’s data section):
AK::SourceLocation
AK::SourceLocation (Ladybird’s equivalent of C++20 std::source_location) can be added as a default argument to
capture the caller’s file, line, and function name without preprocessor macros:
