Methods and catalogs

Error codes

The stable C-ABI status codes SENTIL returns, what each one means, the core error it corresponds to, and how every language binding surfaces it as an idiomatic error.

Nothing a caller does aborts the library. Every fallible operation reports a typed error, and across the C ABI that error travels as a stable numeric code paired with a human-readable message. The codes are sentil_error_t, defined in sentil.h; SENTIL_OK is zero and the rest signal failure. The numbers do not change between releases, so a binding can switch on them.

The codes

CodeNameMeaning
0SENTIL_OKsuccess
1SENTIL_ERR_NULL_POINTERa required handle, string, or array argument was null
2SENTIL_ERR_UTF8a string argument was not valid UTF-8
3SENTIL_ERR_PARSEthe formula failed to parse; the message carries the line and column
4SENTIL_ERR_UNKNOWN_VARIABLEa predicate names a signal the trace does not carry
5SENTIL_ERR_EVALUATIONan evaluation fault: division by zero, an unknown or wrong-arity function, or a bare probabilistic operator evaluated deterministically
6SENTIL_ERR_TRACEa malformed trace: non-monotonic time, a non-finite sample, mismatched signal lengths, an empty trace, or a packed-length mismatch
7SENTIL_ERR_NOT_PROBABILISTICa statistical method received a formula not wrapped in P
8SENTIL_ERR_INVALID_NOISE_MODELa noise-model parameter outside its domain
9SENTIL_ERR_INVALID_CONFIGa run configuration outside its valid range
10SENTIL_ERR_FITa fitter received too few or malformed samples
11SENTIL_ERR_INGESTa trace file could not be opened or parsed
12SENTIL_ERR_SPLITTINGa rare-event splitting run failed
13SENTIL_ERR_UNSUPPORTEDan operation a backend cannot take, such as MILP on a non-affine model
14SENTIL_ERR_TRANSPILATIONa GPU shader failed to transpile or validate
15SENTIL_ERR_GPUa GPU device or dispatch fault
16SENTIL_ERR_JSONa formula JSON round-trip failed
17SENTIL_ERR_PANICan internal panic was caught at the boundary and reported rather than aborting the process

Codes 1 and 2 arise only at the C boundary, from a null or non-UTF-8 argument that never reaches the engine. Codes 14 and 15 appear only in a build with the gpu feature. Code 17 is the backstop: a bug that would have unwound past the FFI is caught and turned into a code, so a caller in another language sees an error instead of a crashed process.

A Rust caller never sees these codes; the same failures are the sentil::Error variants, which the boundary folds down. Parse becomes code 3 and UnknownVariable code 4. DivisionByZero, UnknownFunction, ArityMismatch, and ProbabilisticOperator all become code 5, and the trace-shape variants NonMonotonicTime, NonFiniteSample, SignalLengthMismatch, EmptyTrace, and PackedLength all become code 6. Every remaining variant maps to the code of the same name.

Reading the error in C

The last code and message are thread-local. After a call returns a null handle or a failure sentinel, read them before the next call on that thread overwrites them.

sentil_formula_t *phi = sentil_formula_parse("G ((x >");
if (phi == NULL) {
    sentil_error_t code = sentil_get_last_error_code();
    const char *message = sentil_get_last_error();
    fprintf(stderr, "sentil error %d: %s\n", code, message);
}

The message returned by sentil_get_last_error is borrowed and valid only until the next SENTIL call on the thread; never free it. To keep it, copy it with sentil_get_last_error_message.

How each binding surfaces it

Every binding maps the code to its own error type and carries the message through, so a caller never inspects a raw integer.

LanguageSurfaces as
Rustthe sentil::Error enum, matched by variant
PythonSentilError and its subclasses ParseError, SemanticError, EvaluationError
C++a thrown exception or a returned status, per the header's documented contract
Javaa checked SentilException with subclasses and an ErrorCode enum
Juliathe SentilError abstract type with ParseError, SemanticError, EvaluationError, and a SentilErrorCode
MATLABan MException under the sentil: namespace, such as sentil:parse
Cthe thread-local code and message shown above

The message follows the same rules everywhere: it names the offending construct, gives the position when a formula or signal has one, and states what a correct input looks like. For the parser's own diagnostics, see parse errors; for the C surface in full, see the C page. How each binding folds the codes into its three error subtypes, with a caught example per language, is on handle errors across bindings.

Edit this page on GitHub