|
Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
|
Error handling for the runtime. More...
#include <stddef.h>#include <stdint.h>Go to the source code of this file.
Data Structures | |
| struct | srn_trace_frames_t |
| This is how we create a traceback for the C level code in the runtime lib. More... | |
| struct | srn_error_t |
| A runtime error, a tag classifying the failure and a human-readable message. More... | |
Macros | |
| #define | ERROR_HEADER srn_error_t *maybe_error |
| The first member every fallible data structure embeds (see the file note above). | |
| #define | TRACE_FRAME_DEPTH 32 |
| #define | HAS_ERROR(x) |
| True when x – a value carrying an ERROR_HEADER – has an error attached. | |
| #define | PUSH_TRACE(ctx, x) |
| #define | PUSH_AND_MOVE(ctx, from, to) |
| #define | ERR(ctx, err, msg) |
| #define | ERR_FROM(ctx, src) |
| #define | FAIL(ctx, T, err, msg) |
Typedefs | |
| typedef enum srn_error_tag_t | srn_error_tag_t |
| The kind of a failure. | |
| typedef enum srn_error_layer_t | srn_error_layer_t |
| typedef struct srn_trace_frames_t | srn_trace_frames_t |
| This is how we create a traceback for the C level code in the runtime lib. | |
| typedef struct srn_error_t | srn_error_t |
| A runtime error, a tag classifying the failure and a human-readable message. | |
Enumerations | |
| enum | srn_error_tag_t { ABSURD , NOT_IMPLEMENTED , SEQ_LIMIT_REACHED , AL_LIMIT_REACHED , SM_BUFFER_ID_EXHAUSTED , INDEX_OUT_OF_BOUND , CORRUPTED_SEQ , CORRUPTED_ARRAY_LIST , FAILED_TO_ADD_MODULE , JIT_IR_PARSE_FAILED , JIT_SYMBOL_NOT_FOUND , JIT_SYMBOL_ALREADY_DEFINED , EMPTY_NAMESPACE_NAME , EMPTY_SYMBOL_NAME , STRING_LENGTH_LIMIT_EXCEEDED , WRONG_RANGE , EPOLL_INIT_FAILED , EPOLL_EVENT_FD_FAILED , EPOLL_FAILED_TO_ADD_FD , CONNECTION_REFUSED , CONNECTION_RESET , CONNECTION_ABORTED , BROKEN_PIPE , BAD_DESCRIPTOR , TIMED_OUT , CANCELED , NOT_CONNECTED , ADDRESS_IN_USE , HOST_UNREACHABLE , NETWORK_UNREACHABLE , MESSAGE_TOO_LONG , TOO_MANY_OPEN_FILES , PERMISSION_DENIED , OUT_OF_MEMORY , NOT_FOUND , ALREADY_EXISTS , IS_A_DIRECTORY , NOT_A_DIRECTORY , NO_SPACE , INVALID_ARGUMENT , CHANNEL_BUSY , MEMORY_MAP_FAILED , IR_PARSE_ERROR , UNKNOWN_IO_ERROR } |
| The kind of a failure. More... | |
| enum | srn_error_layer_t : uint8_t { SRN_ERR_RUNTIME_LAYER = 0 } |
Functions | |
| void | srn_error_trace_push (const srn_context_t *ctx, srn_error_t *err, void *addr) |
| Append a return address to the trace of a runtime-layer error. | |
| srn_error_t * | srn_errors_make (const srn_context_t *ctx, srn_error_tag_t tag, const char *msg, void *caller) |
| Build an error in ctx's memory, tagged tag and carrying msg. | |
| srn_error_t * | srn_errors_from (const srn_context_t *ctx, const srn_error_t *src, void *caller) |
| Build an error in ctx's memory that carries the layer, tag, message and payload of src, with a trace of its own that starts at caller. | |
| void * | srn_errors_fail (const srn_context_t *ctx, size_t size, size_t alignment, srn_error_tag_t tag, const char *msg, void *caller) |
| Allocate a size/alignment value in ctx, set its ERROR_HEADER (the first member, srn_error_t *maybe_error) to a fresh error, and return it. | |
| char * | srn_error_to_string (const srn_context_t *ctx, const srn_error_t *err) |
| Format err as a newly allocated string of the form [TAG]: msg, allocated in ctx. | |
| srn_error_tag_t | srn_errno_to_tag (int errno_value, srn_error_tag_t default_tag) |
| Map a POSIX errno to error tag. | |
Error handling for the runtime.
An srn_error_t pairs a srn_error_tag_t, naming the kind of failure, with a human-readable message, and is allocated from a srn_context_t. Fallible operations report failures as these explicit error values rather than through return codes or out-of-band state, so an error travels with the data it describes. When the Serene language layer is built, an error can also be lifted into a srn_value_t so the failure is representable inside the language itself.
By Convention, all the data structures that in anyway may, interacting with them may result in an error, must use the ERROR_HEADER macro as the first member. For example:
Following this convention let you use the error handling helpers from this header uniformly across the runtime library.
Definition in file errors.h.
| #define ERR | ( | ctx, | |
| err, | |||
| msg ) |
| #define ERR_FROM | ( | ctx, | |
| src ) |
| #define ERROR_HEADER srn_error_t *maybe_error |
| #define FAIL | ( | ctx, | |
| T, | |||
| err, | |||
| msg ) |
Definition at line 225 of file errors.h.
| #define HAS_ERROR | ( | x | ) |
True when x – a value carrying an ERROR_HEADER – has an error attached.
Takes the struct by value, the way these results are passed and checked.
| #define PUSH_AND_MOVE | ( | ctx, | |
| from, | |||
| to ) |
| #define PUSH_TRACE | ( | ctx, | |
| x ) |
| typedef enum srn_error_layer_t srn_error_layer_t |
| typedef struct srn_error_t srn_error_t |
A runtime error, a tag classifying the failure and a human-readable message.
| typedef enum srn_error_tag_t srn_error_tag_t |
The kind of a failure.
Each srn_error_t carries one of these.
| typedef struct srn_trace_frames_t srn_trace_frames_t |
This is how we create a traceback for the C level code in the runtime lib.
It's similar to how Zig handles it as well. The hard part is to remember to call __builtin_return_address(0) every time we return an error and add the address to this array. Later we can use dladdr on POSIX (and SymFromAddr on Windows) to resolve the function name, and look up the line number in DWARF data when printing the error.
| enum srn_error_layer_t : uint8_t |
| Enumerator | |
|---|---|
| SRN_ERR_RUNTIME_LAYER | |
Definition at line 150 of file errors.h.
| enum srn_error_tag_t |
The kind of a failure.
Each srn_error_t carries one of these.
Definition at line 92 of file errors.h.
| srn_error_tag_t srn_errno_to_tag | ( | int | errno_value, |
| srn_error_tag_t | default_tag ) |
Map a POSIX errno to error tag.
Note: an errno with no mapping yields default_tag, so the caller picks the fallback that fits its domain. Defined on POSIX platforms. a non-POSIX backend should supply its own native-code mapping.
|
nodiscard |
Format err as a newly allocated string of the form [TAG]: msg, allocated in ctx.
Returns [UNKNOWN]: <null> when err is null.
Definition at line 133 of file errors.c.
| void srn_error_trace_push | ( | const srn_context_t * | ctx, |
| srn_error_t * | err, | ||
| void * | addr ) |
Append a return address to the trace of a runtime-layer error.
Allocates frames from ctx on the first call. Silently does nothing when the trace is full or the error is not a runtime-layer error.
Definition at line 177 of file errors.c.
|
nodiscard |
Allocate a size/alignment value in ctx, set its ERROR_HEADER (the first member, srn_error_t *maybe_error) to a fresh error, and return it.
The result is a valid fallible value whose HAS_ERROR is true. Use the FAIL macro, which fills in size/alignment from the target type.
Definition at line 224 of file errors.c.
| srn_error_t * srn_errors_from | ( | const srn_context_t * | ctx, |
| const srn_error_t * | src, | ||
| void * | caller ) |
Build an error in ctx's memory that carries the layer, tag, message and payload of src, with a trace of its own that starts at caller.
src is not written to, so this is the way to take a trace on an error that is shared or immutable, such as the reactor's static IO errors. A runtime layer src with frames has them copied, so the earlier trace is kept. The ERR_FROM macro supplies caller.
Definition at line 207 of file errors.c.
| srn_error_t * srn_errors_make | ( | const srn_context_t * | ctx, |
| srn_error_tag_t | tag, | ||
| const char * | msg, | ||
| void * | caller ) |
Build an error in ctx's memory, tagged tag and carrying msg.
caller is the return address of the call site (pass __builtin_return_address(0)) and is recorded as the first frame of the trace. The ERR macro supplies it automatically.
Definition at line 196 of file errors.c.