Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
errors.h
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <lxsameer@lxsameer.com>
4 *
5 * This library is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19/** @file
20
21 Error handling for the runtime.
22
23 An `srn_error_t` pairs a `srn_error_tag_t`, naming the kind of failure, with a
24 human-readable message, and is allocated from a `srn_context_t`. Fallible
25 operations report failures as these explicit error values rather than through
26 return codes or out-of-band state, so an error travels with the data it
27 describes. When the Serene language layer is built, an error can also be lifted
28 into a `srn_value_t` so the failure is representable inside the language
29 itself.
30
31 ## IMPORTANT NOTE: ##
32
33 By Convention, all the data structures that in anyway may, interacting with
34 them may result in an error, must use the ERROR_HEADER macro as the first
35 member. For example:
36
37 ```c
38 typedef struct foo {
39 ERROR_HEADER
40 bar other;
41 ...
42 } foo;
43 ```
44 Following this convention let you use the error handling helpers from this
45 header uniformly across the runtime library.
46*/
47
48#pragma once
49
50/**
51 * The first member every fallible data structure embeds (see the file note
52 * above). Holds the error attached to a value, or null when the value is
53 * good.
54 */
55#include <stddef.h>
56
57#ifdef __cplusplus
58extern "C" {
59#endif
60
61#define ERROR_HEADER srn_error_t *maybe_error
62
63/**
64 * True when `x` -- a value carrying an `ERROR_HEADER` -- has an error
65 * attached. Takes the struct by value, the way these results are passed and
66 * checked.
67 */
68#define HAS_ERROR(x) ((x).maybe_error != nullptr)
69
70#define IF_HAS_ERROR_RETURN_WITH(x, result) \
71 if (HAS_ERROR((x))) { \
72 (result).maybe_error = (x).maybe_error; \
73 return (result); \
74 }
75
76typedef struct srn_context_t srn_context_t;
77
78#ifdef SRN_WITH_SERENE
79typedef struct srn_value_t srn_value_t;
80typedef struct srn_metadata_t srn_metadata_t;
81#endif
82
83/**
84 * The kind of a failure. Each `srn_error_t` carries one of these.
85 */
86typedef enum srn_error_tag_t {
95 /// The JIT could not parse a module's LLVM IR or bitcode.
97 /// A JIT symbol lookup found no symbol of that name.
99 /// A JIT symbol definition collided with a name already defined.
108
109 // IO operation failures, reactor backends will maps their platform
110 // errors to these tags.
131 /// The request itself is malformed (an empty POLL interest mask, for
132 /// example), so retrying it unchanged can never succeed.
134 /// The channel already has a full ring's worth of operations in flight.
135 /// Transient by construction, it clears as the worker consumes
136 /// completions, so the caller can retry.
139
142
143/**
144 * A runtime error, a tag classifying the failure and a human-readable
145 * message.
146 */
151
152/**
153 * Build an error in `ctx`'s memory, tagged `tag` and carrying `msg`. Returns
154 * the error to attach to a value's `maybe_error` (or to inspect directly). The
155 * ERR macro below is the shorthand for the common call.
156 */
157srn_error_t *srn_errors_make(const srn_context_t *ctx, srn_error_tag_t tag, const char *msg);
158
159/**
160 * Allocate a `size`/`alignment` value in `ctx`, set its ERROR_HEADER (the
161 * first member, `srn_error_t *maybe_error`) to a fresh error, and return it.
162 * The result is a valid fallible value whose `HAS_ERROR` is true. Use the
163 * FAIL macro, which fills in `size`/`alignment` from the target type.
164 */
165[[nodiscard]] [[gnu::nonnull(1)]]
166void *srn_errors_fail(
167 const srn_context_t *ctx, size_t size, size_t alignment, srn_error_tag_t tag, const char *msg
168);
169
170#define ERR(ctx, err, msg) srn_errors_make(ctx, err, msg)
171#define FAIL(ctx, T, err, msg) ((T *)srn_errors_fail(ctx, sizeof(T), alignof(T), err, msg))
172
173/**
174 * Map a POSIX `errno` to error tag.
175 * Note: an `errno` with no mapping yields `default_tag`, so the caller picks the
176 * fallback that fits its domain. Defined on POSIX platforms. a non-POSIX backend should supply its
177 * own native-code mapping.
178 */
180
181#ifdef SRN_WITH_SERENE
182/**
183 * Lift an existing `srn_error_t` into a Serene value, so a failure already
184 * produced by the substrate can be returned through the language layer.
185 */
187srn_errors_err_to_value(srn_context_t *ctx, srn_metadata_t *metadata, srn_error_t *err);
188/**
189 * Created an error as a value. In compare to `srn_errors_make` this function
190 * populates the `sr_value_t` data structure, so the returning value can be
191 * used in Serene lang directly.
192 */
193srn_value_t *srn_errors_make_error(
194 srn_context_t *ctx, srn_metadata_t *metadata, srn_error_tag_t tag, const char *msg
195);
196#endif
197
198#ifdef __cplusplus
199}
200#endif
srn_error_tag_t
The kind of a failure.
Definition errors.h:86
@ AL_LIMIT_REACHED
Definition errors.h:90
@ EPOLL_EVENT_FD_FAILED
Definition errors.h:106
@ NOT_IMPLEMENTED
Definition errors.h:88
@ BROKEN_PIPE
Definition errors.h:114
@ HOST_UNREACHABLE
Definition errors.h:120
@ CORRUPTED_SEQ
Definition errors.h:92
@ CORRUPTED_ARRAY_LIST
Definition errors.h:93
@ EMPTY_NAMESPACE_NAME
Definition errors.h:101
@ JIT_IR_PARSE_FAILED
The JIT could not parse a module's LLVM IR or bitcode.
Definition errors.h:96
@ NETWORK_UNREACHABLE
Definition errors.h:121
@ STRING_LENGTH_LIMIT_EXCEEDED
Definition errors.h:103
@ IS_A_DIRECTORY
Definition errors.h:128
@ INVALID_ARGUMENT
The request itself is malformed (an empty POLL interest mask, for example), so retrying it unchanged ...
Definition errors.h:133
@ CHANNEL_BUSY
The channel already has a full ring's worth of operations in flight.
Definition errors.h:137
@ ABSURD
Definition errors.h:87
@ WRONG_RANGE
Definition errors.h:104
@ JIT_SYMBOL_ALREADY_DEFINED
A JIT symbol definition collided with a name already defined.
Definition errors.h:100
@ PERMISSION_DENIED
Definition errors.h:124
@ CONNECTION_RESET
Definition errors.h:112
@ UNKNOWN_IO_ERROR
Definition errors.h:140
@ TOO_MANY_OPEN_FILES
Definition errors.h:123
@ JIT_SYMBOL_NOT_FOUND
A JIT symbol lookup found no symbol of that name.
Definition errors.h:98
@ NOT_CONNECTED
Definition errors.h:118
@ CONNECTION_REFUSED
Definition errors.h:111
@ FAILED_TO_ADD_MODULE
Definition errors.h:94
@ INDEX_OUT_OF_BOUND
Definition errors.h:91
@ SEQ_LIMIT_REACHED
Definition errors.h:89
@ CONNECTION_ABORTED
Definition errors.h:113
@ ADDRESS_IN_USE
Definition errors.h:119
@ EPOLL_FAILED_TO_ADD_FD
Definition errors.h:107
@ EPOLL_INIT_FAILED
Definition errors.h:105
@ BAD_DESCRIPTOR
Definition errors.h:115
@ OUT_OF_MEMORY
Definition errors.h:125
@ NOT_FOUND
Definition errors.h:126
@ CANCELED
Definition errors.h:117
@ NOT_A_DIRECTORY
Definition errors.h:129
@ TIMED_OUT
Definition errors.h:116
@ EMPTY_SYMBOL_NAME
Definition errors.h:102
@ MEMORY_MAP_FAILED
Definition errors.h:138
@ MESSAGE_TOO_LONG
Definition errors.h:122
@ ALREADY_EXISTS
Definition errors.h:127
@ NO_SPACE
Definition errors.h:130
srn_error_tag_t srn_errno_to_tag(int errno_value, srn_error_tag_t default_tag)
Map a POSIX errno to error tag.
void * srn_errors_fail(const srn_context_t *ctx, size_t size, size_t alignment, srn_error_tag_t tag, const char *msg)
Allocate a size/alignment value in ctx, set its ERROR_HEADER (the first member, srn_error_t *maybe_er...
Definition errors.c:39
srn_error_t * srn_errors_make(const srn_context_t *ctx, srn_error_tag_t tag, const char *msg)
Build an error in ctx's memory, tagged tag and carrying msg.
Definition errors.c:31
A runtime error, a tag classifying the failure and a human-readable message.
Definition errors.h:147
char * msg
Definition errors.h:149
srn_error_tag_t tag
Definition errors.h:148