layout: true --- class: middle .center[ # errors .accent[ ### forgotten, but not gone] ] ??? > * --- # some apis that return errors ``` std::error_code okApiCall(){ return std::error_code{}; } std::error_code failApiCall(){ return std::errc::io_error; } ``` ??? > * --- # two wrongs don't make a right ``` auto e = failApiCall(); e = failApiCall(); ``` ??? > * errors are ignored by default > * exceptions are not ingored by default --- # two rights are still wrong ``` auto e = okApiCall(); e = okApiCall(); ``` ??? > * --- # Is it a runtime error? .center[ .image-60[ ![](content/semiavoid.gif)]] ??? > * unexpected events happen in systems --- # Is it a code bug? .center[ .image-60[ ![](content/traincrossing.gif)]] ??? > * flaws in systems should result in a stop and a report > * this is intended to ensure that code bugs do not ship --- class: middle .center[ .accent[ # what should happen if an error is forgotten?]] ??? > * --- class: middle .center[ .accent[ # how would a forgotten error be detected?]] ??? > * --- # errors need to get a life .. time ``` // begin scope auto e = failApiCall(); // end scope `boom` // begin scope e = failApiCall(); // end scope `boom` ``` ??? > * --- # go BOOM ``` unique_error_code ge; // default is safe ge.reset(okApiCall()); // unssafe after calling api // `boom` ge.reset(okApiCall()); ``` ??? > * --- # go BOOM ``` unique_error_code ge; // default is safe ge.reset(okApiCall()); // unssafe after calling api // `boom` ``` ??? > * --- # no BOOM ``` unique_error_code ge; // default is safe ge.reset(okApiCall()); // unssafe after calling api if (!ge.ok()) { return ge.release(); } // safe once it is checked ``` -- ``` ge.reset(okApiCall()); // unssafe after calling api return ge.release(); // safe once it is released ``` ??? > * --- # example implementation for a Win32 winerror type ``` enum class winerror_error : DWORD {}; inline winerror_error winerror_cast(DWORD raw) { return static_cast
(raw); } template<> struct error_traits
{ using value_type = winerror_error; static inline winerror_error initiate() { return winerror_cast(ERROR_SUCCESS); } static inline bool ok(winerror_error winerror) { return winerror == winerror_cast(ERROR_SUCCESS); } }; ``` --- # example implementation for a Win32 winerror type ``` using unique_winerror = gsl::unique_error
; inline unique_winerror make_winerror_if(BOOL is_last_error) { unique_winerror result; if (is_last_error) { return result.reset(GetLastError()); } return result; } ``` --- # example implementation for a Win32 winerror type ``` unique_winerror winerror; PCCERT_CONTEXT certcontext = CertCreateCertificateContext( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &key.cert[0], key.cert.size() ); winerror = make_winerror_if(!certcontext); if (!winerror) { std::wcout << L"could not get cert context" << std::endl; } ``` [https://github.com/kirkshoop/authentication](https://github.com/kirkshoop/authentication) --- # where is the code? [github](https://github.com/kirkshoop/GSL/commit/a8c46e58d318158aec5d9c53236428d0ae39703a) ??? > *