better onfail handling - more regular and simpler language semantics this way

This commit is contained in:
Richard Thier 2024-09-24 13:04:20 +02:00
parent 218f6eacb1
commit 2e297f0769

View File

@ -903,9 +903,9 @@ Megj.: Itt is talán a második formát kéne csak engdni? Lásd "tagged union"-
Megj.: Esetleg megfontolni miként segíti ez az állapotgépek használatát / parzer építést? Esetleg a 2D switch-el?
## Exception és hibakezelés
## Kivétel és hibakezelés
- Exception-ök nincsenek
- Exception-ök (kivételek) nincsenek!
- Go és rust-hoz hasonló hibakezelés az szerintem jó ötlet, de egy-az-egyben egyik se tetszik ebből a kettőből. Jó ha van valami syntax sugar és az is, ha kötelezővé tudod tenni az error-t is visszaadó függvény hívásánál a hibakezelést, vagy tovább propagálást.
- Stack unwinding, meg ilyesmi sincs így: egyszerűen syntax sugar van, hogy fordításkor kikényszerítheted a hiba lekezelését ha valaki hív téged. Az egyetlen kérdés, hogy mi történik a tagged union-os esetben ha polimorfizmus van és más-más esetben lehet, vagy nem lehet hiba... hát a válasz az, hogy a függvény deklarációban benne kell legyen a hiba szóval a hiba maga itt nem polimorf (vagyis csak ugyan ennyire, de nem lehet olyan, hogy valamely tagged union variáns olyan hibát dob és úgy, ahogy az nincs interfészben jelölve).
@ -966,29 +966,48 @@ FONTOS (destruktor error):
}
}
void dostuff() {
/**
* Does the stuff...
*
* @param sc A socket connection to send ackknowledgements from the primary database
* @returns true when socket message was sent and db1 got data (db2 might not)
*/
bool dostuff(SocketConnection &sc) {
DatabaseConnection dc;
dc.insert(...);
dc.commit();
sc.send(dc.ack); // (*)
DatabaseConnection dc2;
dc2.insert(...);
dc2.commit();
SocketConnection sc;
sc.insert(...);
sc.commit();
} onfail(DatabaseError dc.err) { // TODO: Jó-e a syntax? Itt a dc adja meg minek a dekonstruktora futott (elhagyható)
CannotClose:
...
} onfail(DatabaseError dc2.err) {
return dc.ack.ok();
} onfail(DatabaseError err) {
CannotClose:
// The objects are still in scope here
// but their destructors might have
// been already called (or error flags present)
if(dc.failed_flag) {
log(LogLevel.ERROR, "Primary database dostuff error!");
return false;
} else if(dc2.failed_flag) {
log(LogLevel.ERROR, "Secondary database dostuff error!");
return true;
}
// You can have code that is generic here
...
} onfail(SocketError err) {
CannotClose:
...
// You can add multiple clauses and
// handle non-destructor errors too.
// If we are here, code after (*) didn't run!
CannotSend:
log(LogLevel.ERROR, "Could not send ack through network!");
// return value is needed here, because we might get here
// for regular failures - instead of destructor errors too!
return false;
}
Megjegyzés: A scope végére helyezett onfail talán kiválthatná a lokálisat / függvényhívás pontján lévőt?
Ekkor talán javasolt lenne a scope-osnál a teljes típust kiírni, mert többféle tagged enum lehet?
Megjegyzés: A scope végére helyezett onfail talán kiválthatja a lokálisat / függvényhívás pontján lévőt, de mindkettő lehet!
Ezért javasolt a scope-osnál szükség lehet - mint az látható - több error kezelőt írni (típusonként egyet).
Megjegyzés: thread_local-ba tehet mondjuk error esetén void* plusz adatot az error kiváltó kód (ha kell). (szabvány v egyedi?)