Library: discontinue setting error flag from Exceptions (see #1341)
While seemingly subtle, this is a ''deep change.'' Up to now, the project attempted to maintain two mutually disjoint systems of error reporting: C-style error flags and C++ exceptions. Most notably, an attempt was made to keep both error states synced. During the recent integration efforts, this increasingly turned out as an obstacle and source for insidious problems (like deadlocks). As a resolve, hereby the relation of both systems is **clarified**: * C-style error flags shall only be set and used by C code henceforth * C++ exceptions can (optionally) be thrown by retrieving the C-style error code * but the opposite is now ''discontinued'' : Exceptions ''do not set'' the error flag anymore
This commit is contained in:
parent
fdd8e2d595
commit
9cb0a9b680
7 changed files with 47 additions and 61 deletions
|
|
@ -213,6 +213,8 @@ namespace lib {
|
||||||
catch (lumiera::Error & ex)
|
catch (lumiera::Error & ex)
|
||||||
{
|
{
|
||||||
WARN (progress, "Exception while closing AllocationCluster: %s", ex.what());
|
WARN (progress, "Exception while closing AllocationCluster: %s", ex.what());
|
||||||
|
const char* errID = lumiera_error();
|
||||||
|
TRACE (debugging, "Error flag was: %s", errID);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -96,16 +96,13 @@ namespace lumiera {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @note we set the C-style errorstate as a side effect */
|
|
||||||
Error::Error (string description, lumiera_err const id) noexcept
|
Error::Error (string description, lumiera_err const id) noexcept
|
||||||
: std::exception{}
|
: std::exception{}
|
||||||
, id_{id}
|
, id_{id}
|
||||||
, msg_{error::default_usermsg (this)}
|
, msg_{error::default_usermsg (this)}
|
||||||
, desc_{description}
|
, desc_{description}
|
||||||
, cause_{}
|
, cause_{}
|
||||||
{
|
{ }
|
||||||
lumiera_error_set (this->id_, description.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error::Error (std::exception const& cause,
|
Error::Error (std::exception const& cause,
|
||||||
|
|
@ -117,7 +114,6 @@ namespace lumiera {
|
||||||
, cause_{extractCauseMsg(cause)}
|
, cause_{extractCauseMsg(cause)}
|
||||||
{
|
{
|
||||||
string detailInfo{description + (isnil(cause_)? "" : " | cause = "+cause_)};
|
string detailInfo{description + (isnil(cause_)? "" : " | cause = "+cause_)};
|
||||||
lumiera_error_set (this->id_, detailInfo.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ namespace lumiera {
|
||||||
{
|
{
|
||||||
throw error::Flag( error::detailInfo()
|
throw error::Flag( error::detailInfo()
|
||||||
, errorFlag);
|
, errorFlag);
|
||||||
} } //causes the error state to be set
|
} }
|
||||||
|
|
||||||
/** Check the lumiera error state and throw a specific exception
|
/** Check the lumiera error state and throw a specific exception
|
||||||
* in case a non-cleared errorflag is detected. No-op else.
|
* in case a non-cleared errorflag is detected. No-op else.
|
||||||
|
|
|
||||||
|
|
@ -154,10 +154,12 @@ namespace stage {
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
if (!lumiera_error_peek())
|
const char* errID = lumiera_error(); // clear C-style error flag
|
||||||
LUMIERA_ERROR_SET (stage, STATE, "unexpected error when starting the GUI thread");
|
WARN (stage, "Unexpected error while starting the GUI thread.");
|
||||||
|
if (errID)
|
||||||
|
TRACE (stage, "Error flag was: %s", errID);
|
||||||
return false;
|
return false;
|
||||||
} // note: lumiera_error state remains set
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace stage
|
} // namespace stage
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ TESTING "Exception handling and diagnostics" ./test-suite --group=common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST "ExceptionError_test" ExceptionError_test <<END
|
TEST "Exceptions and Error flags" ExceptionError_test <<END
|
||||||
out: caught: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything\? \(don't panic\)...the answer is: 42
|
out: caught: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything\? \(don't panic\)...the answer is: 42
|
||||||
out: caught lumiera::Error: LUMIERA_ERROR_DERIVED:convoluted exception
|
out: caught lumiera::Error: LUMIERA_ERROR_DERIVED:convoluted exception
|
||||||
out: caught error::Logic: LUMIERA_ERROR_FATAL:floundered \(test-2\).
|
out: caught error::Logic: LUMIERA_ERROR_FATAL:floundered \(test-2\).
|
||||||
|
|
@ -16,7 +16,6 @@ out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external ser
|
||||||
out: 2nd intermediate handler caught: LUMIERA_ERROR_STATE:unforeseen state -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service \(test-8\).....will rethrow as error::Config
|
out: 2nd intermediate handler caught: LUMIERA_ERROR_STATE:unforeseen state -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service \(test-8\).....will rethrow as error::Config
|
||||||
out: caught error::Invalid: LUMIERA_ERROR_CONFIG:misconfiguration -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service \(test-8\)\.
|
out: caught error::Invalid: LUMIERA_ERROR_CONFIG:misconfiguration -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service \(test-8\)\.
|
||||||
out: caught lumiera::Error: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything\? \(what is the answer\?\)\.
|
out: caught lumiera::Error: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything\? \(what is the answer\?\)\.
|
||||||
out: caught error::Logic: LUMIERA_ERROR_LOGIC:internal logic broken \(the big bang\). -- caused by: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything\? \(what is the answer\?\)\.
|
|
||||||
return: 0
|
return: 0
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,12 +67,10 @@ namespace lumiera {
|
||||||
class ExceptionError_test : public Test
|
class ExceptionError_test : public Test
|
||||||
{
|
{
|
||||||
typedef ExceptionError_test test;
|
typedef ExceptionError_test test;
|
||||||
virtual void run (Arg arg)
|
|
||||||
|
virtual void
|
||||||
|
run (Arg)
|
||||||
{
|
{
|
||||||
if (0 < arg.size() and arg[1]=="terminate")
|
|
||||||
terminateUnknown();
|
|
||||||
|
|
||||||
|
|
||||||
catcher (&test::throwSpecial, "");
|
catcher (&test::throwSpecial, "");
|
||||||
catcher (&test::throwDerived, "test-1");
|
catcher (&test::throwDerived, "test-1");
|
||||||
catcher (&test::throwFatal, "test-2");
|
catcher (&test::throwFatal, "test-2");
|
||||||
|
|
@ -84,7 +82,6 @@ namespace lumiera {
|
||||||
catcher (&test::nestedThrower, "test-7");
|
catcher (&test::nestedThrower, "test-7");
|
||||||
catcher (&test::doubleNestedTh,"test-8");
|
catcher (&test::doubleNestedTh,"test-8");
|
||||||
|
|
||||||
checkErrorIntegration();
|
|
||||||
checkErrorFlagPropagation();
|
checkErrorFlagPropagation();
|
||||||
checkRootCauseChaining();
|
checkRootCauseChaining();
|
||||||
}
|
}
|
||||||
|
|
@ -134,31 +131,7 @@ namespace lumiera {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @test by constructing an lumiera::Error object,
|
void detectErrorflag (string) { throwOnError(); }
|
||||||
* the corresponding lumiera_error state is set automatically
|
|
||||||
*/
|
|
||||||
void checkErrorIntegration()
|
|
||||||
{
|
|
||||||
lumiera_error ();
|
|
||||||
CHECK (not lumiera_error());
|
|
||||||
|
|
||||||
Error err1;
|
|
||||||
Error err2("boo",LERR_(DERIVED));
|
|
||||||
CHECK (err1.getID () == lumiera_error ()); // (we didn't clear the first one!)
|
|
||||||
|
|
||||||
Error err3("boooo",LERR_(DERIVED));
|
|
||||||
CHECK (err3.getID () == lumiera_error ());
|
|
||||||
|
|
||||||
SpecificError err4;
|
|
||||||
CHECK (err4.getID () == LERR_(LIFE_AND_UNIVERSE));
|
|
||||||
CHECK (err4.getID () == lumiera_error ());
|
|
||||||
|
|
||||||
CHECK (not lumiera_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void detectErrorflag (string) { throwOnError(); }
|
|
||||||
void detectErrorflagChained (string msg) { maybeThrow<error::Logic> (msg); }
|
|
||||||
|
|
||||||
|
|
||||||
/** @test verify throwing of Exceptions
|
/** @test verify throwing of Exceptions
|
||||||
|
|
@ -169,12 +142,9 @@ namespace lumiera {
|
||||||
lumiera_error_set(LERR_(LIFE_AND_UNIVERSE), "what is the answer?");
|
lumiera_error_set(LERR_(LIFE_AND_UNIVERSE), "what is the answer?");
|
||||||
CHECK (lumiera_error_peek());
|
CHECK (lumiera_error_peek());
|
||||||
|
|
||||||
catcher (&test::detectErrorflag, "");
|
catcher (&test::detectErrorflag);
|
||||||
CHECK (LERR_(LIFE_AND_UNIVERSE) == lumiera_error_peek());
|
CHECK (not lumiera_error_peek());
|
||||||
|
}// yet translating that into an exception also clears the error flag
|
||||||
catcher (&test::detectErrorflagChained, "the big bang");
|
|
||||||
CHECK (LERR_(LIFE_AND_UNIVERSE) == lumiera_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** @test the chaining of lumiera::Exception objects
|
/** @test the chaining of lumiera::Exception objects
|
||||||
|
|
@ -200,18 +170,6 @@ namespace lumiera {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @test terminate the Application by throwing an undeclared exception.
|
|
||||||
* this should result in the global unknown() handler to be called,
|
|
||||||
* so usually it will terminate the test run.
|
|
||||||
* @note inside error.hpp, an initialisation hook has been installed into
|
|
||||||
* AppState, causing our own unknown() handler to be installed and
|
|
||||||
* invoked, which gives additional diagnostics.*/
|
|
||||||
void terminateUnknown () noexcept
|
|
||||||
{
|
|
||||||
throw Error{"Catch the hedgehog..."};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** a very specific Exception class
|
/** a very specific Exception class
|
||||||
* local to this scope and with
|
* local to this scope and with
|
||||||
* additional behaviour.
|
* additional behaviour.
|
||||||
|
|
@ -238,7 +196,7 @@ namespace lumiera {
|
||||||
/** helper: provides a bunch of catch-clauses and
|
/** helper: provides a bunch of catch-clauses and
|
||||||
* runs the given member functions within
|
* runs the given member functions within
|
||||||
*/
|
*/
|
||||||
void catcher (void (ExceptionError_test::*funky)(string), string context)
|
void catcher (void (ExceptionError_test::*funky)(string), string context ="")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57360,6 +57360,33 @@
|
||||||
<icon BUILTIN="yes"/>
|
<icon BUILTIN="yes"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
<node CREATED="1696123512914" ID="ID_1907944246" MODIFIED="1696123517031" TEXT="Fehlerbehandlung">
|
||||||
|
<node CREATED="1696123519551" ID="ID_1260806652" MODIFIED="1696123525010" TEXT="Status-quo">
|
||||||
|
<node CREATED="1696123526614" ID="ID_494414016" MODIFIED="1696123536532" TEXT="zwei konkurrierende Systeme"/>
|
||||||
|
<node CREATED="1696123537225" ID="ID_1573590963" MODIFIED="1696123548249" TEXT="Versuch, sie miteinander zu verbinden"/>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696109905830" ID="ID_1320347721" MODIFIED="1696123617052" TEXT="konzeptioneller Rahmen nicht klar">
|
||||||
|
<arrowlink COLOR="#fdcfce" DESTINATION="ID_853481552" ENDARROW="Default" ENDINCLINATION="-959;56;" ID="Arrow_ID_1749710199" STARTARROW="None" STARTINCLINATION="-1130;86;"/>
|
||||||
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
|
<node CREATED="1696123584407" ID="ID_100243936" MODIFIED="1696123592153" TEXT="was soll die Fehlerbehandlung leisten?"/>
|
||||||
|
<node CREATED="1696123593053" ID="ID_1989612078" MODIFIED="1696123604000" TEXT="wann darf man die Applikation einfach stoppen"/>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1696123633856" ID="ID_938884061" MODIFIED="1696123679262" TEXT="weiterentwickeln">
|
||||||
|
<icon BUILTIN="pencil"/>
|
||||||
|
<icon BUILTIN="hourglass"/>
|
||||||
|
<node CREATED="1696123685033" ID="ID_1288168258" MODIFIED="1696123908702" TEXT="10/2023 : C-Fehlerflag wird zweitrangig">
|
||||||
|
<linktarget COLOR="#743762" DESTINATION="ID_1288168258" ENDARROW="Default" ENDINCLINATION="-1572;111;" ID="Arrow_ID_1929499179" SOURCE="ID_693954886" STARTARROW="None" STARTINCLINATION="-1669;-68;"/>
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
<node CREATED="1696123727542" ID="ID_1991627324" MODIFIED="1696123743073" TEXT="bidirektionale Verbindung aufgeben"/>
|
||||||
|
<node CREATED="1696123744977" ID="ID_383359061" MODIFIED="1696123762047" TEXT="C-Fehlerflag soll nur noch aus C-Code gesetzt werden">
|
||||||
|
<icon BUILTIN="yes"/>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696123916050" ID="ID_336075850" MODIFIED="1696123953390" TEXT="kein automatisches Setzen mehr beim Erzeugen einer Exception">
|
||||||
|
<icon BUILTIN="flag-yellow"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1667336713909" ID="ID_259014029" MODIFIED="1667336726184" TEXT="Framework">
|
<node CREATED="1667336713909" ID="ID_259014029" MODIFIED="1667336726184" TEXT="Framework">
|
||||||
<font NAME="SansSerif" SIZE="14"/>
|
<font NAME="SansSerif" SIZE="14"/>
|
||||||
|
|
@ -80746,6 +80773,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
||||||
<node CREATED="1696109856041" ID="ID_130019164" MODIFIED="1696110849648" TEXT="Fazit">
|
<node CREATED="1696109856041" ID="ID_130019164" MODIFIED="1696110849648" TEXT="Fazit">
|
||||||
<icon BUILTIN="forward"/>
|
<icon BUILTIN="forward"/>
|
||||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1696109861199" ID="ID_693954886" MODIFIED="1696119872703" TEXT="Entscheidung die Kopplung von C-Flag und Exceptions betreffend">
|
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1696109861199" ID="ID_693954886" MODIFIED="1696119872703" TEXT="Entscheidung die Kopplung von C-Flag und Exceptions betreffend">
|
||||||
|
<arrowlink COLOR="#743762" DESTINATION="ID_1288168258" ENDARROW="Default" ENDINCLINATION="-1572;111;" ID="Arrow_ID_1929499179" STARTARROW="None" STARTINCLINATION="-1669;-68;"/>
|
||||||
<linktarget COLOR="#734d4b" DESTINATION="ID_693954886" ENDARROW="Default" ENDINCLINATION="61;-139;" ID="Arrow_ID_921866413" SOURCE="ID_1910682637" STARTARROW="None" STARTINCLINATION="-390;17;"/>
|
<linktarget COLOR="#734d4b" DESTINATION="ID_693954886" ENDARROW="Default" ENDINCLINATION="61;-139;" ID="Arrow_ID_921866413" SOURCE="ID_1910682637" STARTARROW="None" STARTINCLINATION="-390;17;"/>
|
||||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||||
<icon BUILTIN="yes"/>
|
<icon BUILTIN="yes"/>
|
||||||
|
|
@ -92193,6 +92221,7 @@ class Something
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696109921291" ID="ID_853481552" LINK="https://issues.lumiera.org/ticket/1341" MODIFIED="1696110190077" TEXT="#110 und #1341 Clarify Error handling scheme">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696109921291" ID="ID_853481552" LINK="https://issues.lumiera.org/ticket/1341" MODIFIED="1696110190077" TEXT="#110 und #1341 Clarify Error handling scheme">
|
||||||
<linktarget COLOR="#fdcfce" DESTINATION="ID_853481552" ENDARROW="Default" ENDINCLINATION="-959;56;" ID="Arrow_ID_275745687" SOURCE="ID_1712639748" STARTARROW="None" STARTINCLINATION="-1085;66;"/>
|
<linktarget COLOR="#fdcfce" DESTINATION="ID_853481552" ENDARROW="Default" ENDINCLINATION="-959;56;" ID="Arrow_ID_275745687" SOURCE="ID_1712639748" STARTARROW="None" STARTINCLINATION="-1085;66;"/>
|
||||||
|
<linktarget COLOR="#fdcfce" DESTINATION="ID_853481552" ENDARROW="Default" ENDINCLINATION="-959;56;" ID="Arrow_ID_1749710199" SOURCE="ID_1320347721" STARTARROW="None" STARTINCLINATION="-1130;86;"/>
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694440562933" ID="ID_1529688085" LINK="https://issues.lumiera.org/ticket/1338" MODIFIED="1694795034628" TEXT="#1338 Non-standard Play-processing">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694440562933" ID="ID_1529688085" LINK="https://issues.lumiera.org/ticket/1338" MODIFIED="1694795034628" TEXT="#1338 Non-standard Play-processing">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue