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(...);
}