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 <[email protected]>
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#define ERROR_HEADER srn_error_t *maybe_error
57
58/**
59 * True when `x` -- a value carrying an `ERROR_HEADER` -- has an error
60 * attached. Takes the struct by value, the way these results are passed and
61 * checked.
62 */
63#define HAS_ERROR(x) ((x).maybe_error != nullptr)
64
65typedef struct srn_context_t srn_context_t;
66
67#ifdef SRN_WITH_SERENE
68typedef struct srn_value_t srn_value_t;
69typedef struct srn_metadata_t srn_metadata_t;
70#endif
71
72/**
73 * The kind of a failure. Each `srn_error_t` carries one of these.
74 */
75typedef enum srn_error_tag_t {
88
89 // IO operation failures, reactor backends will maps their platform
90 // errors to these tags.
111 /// The request itself is malformed (an empty POLL interest mask, for
112 /// example), so retrying it unchanged can never succeed.
114 /// The channel already has a full ring's worth of operations in flight.
115 /// Transient by construction, it clears as the worker consumes
116 /// completions, so the caller can retry.
120
121/**
122 * A runtime error, a tag classifying the failure and a human-readable
123 * message.
124 */
129
130/**
131 * Build an error in `ctx`'s memory, tagged `tag` and carrying `msg`. Returns
132 * the error to attach to a value's `maybe_error` (or to inspect directly). The
133 * ERR macro below is the shorthand for the common call.
134 */
135srn_error_t *srn_errors_make(const srn_context_t *ctx, srn_error_tag_t tag, const char *msg);
136
137/**
138 * Allocate a `size`/`alignment` value in `ctx`, set its ERROR_HEADER (the
139 * first member, `srn_error_t *maybe_error`) to a fresh error, and return it.
140 * The result is a valid fallible value whose `HAS_ERROR` is true. Use the
141 * FAIL macro, which fills in `size`/`alignment` from the target type.
142 */
143[[nodiscard]] [[gnu::nonnull(1)]]
144void *srn_errors_fail(
145 const srn_context_t *ctx, size_t size, size_t alignment, srn_error_tag_t tag, const char *msg
146);
147
148#define ERR(ctx, err, msg) srn_errors_make(ctx, err, msg)
149#define FAIL(ctx, T, err, msg) ((T *)srn_errors_fail(ctx, sizeof(T), alignof(T), err, msg))
150
151/**
152 * Map a POSIX `errno` to error tag.
153 * Note: an `errno` with no mapping yields `default_tag`, so the caller picks the
154 * fallback that fits its domain. Defined on POSIX platforms. a non-POSIX backend should supply its
155 * own native-code mapping.
156 */
158
159#ifdef SRN_WITH_SERENE
160/**
161 * Lift an existing `srn_error_t` into a Serene value, so a failure already
162 * produced by the substrate can be returned through the language layer.
163 */
165srn_errors_err_to_value(srn_context_t *ctx, srn_metadata_t *metadata, srn_error_t *err);
166/**
167 * Created an error as a value. In compare to `srn_errors_make` this function
168 * populates the `sr_value_t` data structure, so the returning value can be
169 * used in Serene lang directly.
170 */
171srn_value_t *srn_errors_make_error(
172 srn_context_t *ctx, srn_metadata_t *metadata, srn_error_tag_t tag, const char *msg
173);
174#endif
srn_error_tag_t
The kind of a failure.
Definition errors.h:75
@ EPOLL_EVENT_FD_FAILED
Definition errors.h:86
@ BROKEN_PIPE
Definition errors.h:94
@ HOST_UNREACHABLE
Definition errors.h:100
@ CORRUPTED_SEQ
Definition errors.h:79
@ EMPTY_NAMESPACE_NAME
Definition errors.h:81
@ NETWORK_UNREACHABLE
Definition errors.h:101
@ STRING_LENGTH_LIMIT_EXCEEDED
Definition errors.h:83
@ IS_A_DIRECTORY
Definition errors.h:108
@ INVALID_ARGUMENT
The request itself is malformed (an empty POLL interest mask, for example), so retrying it unchanged ...
Definition errors.h:113
@ CHANNEL_BUSY
The channel already has a full ring's worth of operations in flight.
Definition errors.h:117
@ ABSURD
Definition errors.h:76
@ WRONG_RANGE
Definition errors.h:84
@ PERMISSION_DENIED
Definition errors.h:104
@ CONNECTION_RESET
Definition errors.h:92
@ UNKNOWN_IO_ERROR
Definition errors.h:118
@ TOO_MANY_OPEN_FILES
Definition errors.h:103
@ NOT_CONNECTED
Definition errors.h:98
@ CONNECTION_REFUSED
Definition errors.h:91
@ FAILED_TO_ADD_MODULE
Definition errors.h:80
@ INDEX_OUT_OF_BOUND
Definition errors.h:78
@ SEQ_LIMIT_REACHED
Definition errors.h:77
@ CONNECTION_ABORTED
Definition errors.h:93
@ ADDRESS_IN_USE
Definition errors.h:99
@ EPOLL_FAILED_TO_ADD_FD
Definition errors.h:87
@ EPOLL_INIT_FAILED
Definition errors.h:85
@ BAD_DESCRIPTOR
Definition errors.h:95
@ OUT_OF_MEMORY
Definition errors.h:105
@ NOT_FOUND
Definition errors.h:106
@ CANCELED
Definition errors.h:97
@ NOT_A_DIRECTORY
Definition errors.h:109
@ TIMED_OUT
Definition errors.h:96
@ EMPTY_SYMBOL_NAME
Definition errors.h:82
@ MESSAGE_TOO_LONG
Definition errors.h:102
@ ALREADY_EXISTS
Definition errors.h:107
@ NO_SPACE
Definition errors.h:110
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:125
char * msg
Definition errors.h:127
srn_error_tag_t tag
Definition errors.h:126