Files
saselang-bible/examples/018-result-erreurs-et-exceptions-examples.md
2026-09-13 10:20:16 +02:00

2.9 KiB

Exemples / DO-DON'T — Chapitre 18 — Result, erreurs, exceptions et faults

Document compagnon. Les exemples illustrent les règles du chapitre ; la formulation normative reste dans le chapitre lui-même.

Hiérarchie

Object
└── Error
    ├── ResultError
    ├── Exception
    └── Fault
public final class ParseError extends ResultError {
}

public final class FileNotFoundException extends Exception {
}

public final class IndexOutOfBoundsFault extends Fault {
}

ResultError

DO : utiliser Result lorsque l'échec est une valeur normale à inspecter explicitement.

func parseExternalInput(String input) -> Result<Value, ParseError> {
    ...
}

DON'T : placer une Exception ou un Fault dans le paramètre erreur de Result.

Result<Value,FileNotFoundException> // ERROR
Result<Value,IndexOutOfBoundsFault> // ERROR

Exception, throw et throws

func readConfig(String path) -> Config
    throws IOException
{
    ...
}

Un retour direct est compatible avec throws.

throw FileNotFoundException(...); // OK
throw IndexOutOfBoundsFault(...); // ERROR
throw ParseError(...);            // ERROR

Fault, fault et faults

method elementAt(uint64 index) -> T
    faults IndexOutOfBoundsFault
{
    if (index >= this::length()) {
        fault IndexOutOfBoundsFault(index, this::length());
    }

    ...
}

La clause faults est optionnelle et non exhaustive.

DO : appeler sans cérémonie lorsque le fault n'est pas un chemin normal à traiter.

T value = list::elementAt(index);

DO : capturer explicitement lorsque le programme veut réellement récupérer ce cas.

try {
    T value = list::elementAt(index);
} catch (IndexOutOfBoundsFault faultValue) {
    ...
}

Aucune propagation de faults n'est obligatoire :

func outer() -> Void {
    inner(); // inner peut déclarer faults SomeFault
    return Void;
}

catch

Valide :

catch (IOException error) {
    ...
}

catch (IteratorInvalidatedFault faultValue) {
    ...
}

Invalide :

catch (Error error)       // ERROR
catch (ResultError error) // ERROR

catch ne peut cibler que Exception, Fault ou leurs descendants.

Direct versus valeur conditionnelle

Accès affirmatif :

User user = users[id]; // absence -> KeyNotFoundFault

Absence normale :

Option<User> user = users::get(id);

Le Core ne doit pas créer automatiquement une variante tryOp() uniquement pour transporter le même échec dans Result.

Erreur statique versus fault runtime

StaticArray<int32,3> values = [1, 2, 3];
int32 a = values[5]; // ERROR compilation
uint64 index = readIndex();
int32 b = values[index]; // peut produire IndexOutOfBoundsFault au runtime

Un statement fault explicite reste évidemment valide :

if (!state::isValid()) {
    fault InvalidStateFault(...);
}