1 /* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9 #ifndef SQUID__TEXTEXCEPTION_H 10 #define SQUID__TEXTEXCEPTION_H 11 12 #include "base/Here.h" 13 14 #include <stdexcept> 15 16 class SBuf; 17 18 /// an std::runtime_error with thrower location info 19 class TextException: public std::runtime_error 20 { 21 22 public: TextException(const char * message,const SourceLocation & location)23 TextException(const char *message, const SourceLocation &location): 24 std::runtime_error(message), 25 where(location) 26 {} 27 28 TextException(SBuf message, const SourceLocation &location); 29 30 TextException(const TextException &) = default; 31 TextException(TextException &&) = default; 32 TextException& operator=(const TextException &) = default; 33 34 /* std::runtime_error API */ 35 virtual ~TextException() throw() override; 36 virtual const char *what() const throw() override; 37 38 /// same-location exceptions have the same ID id()39 SourceLocationId id() const { return where.id(); } 40 41 /// dumps the exception text into the stream 42 std::ostream &print(std::ostream &) const; 43 44 /// code location related to the exception; usually the thrower location 45 SourceLocation where; 46 47 // TODO: Add support for arbitrary (re)thrower-supplied details: 48 // std::tuple<Details...> details; 49 }; 50 51 /// prints active (i.e., thrown but not yet handled) exception 52 std::ostream &CurrentException(std::ostream &); 53 54 /// legacy convenience macro; it is not difficult to type Here() now 55 #define TexcHere(msg) TextException((msg), Here()) 56 57 /// Like assert() but throws an exception instead of aborting the process 58 /// and allows the caller to specify a custom exception message. 59 #define Must2(condition, message) \ 60 do { \ 61 if (!(condition)) { \ 62 const TextException Must_ex_((message), Here()); \ 63 debugs(0, 3, Must_ex_.what()); \ 64 throw Must_ex_; \ 65 } \ 66 } while (/*CONSTCOND*/ false) 67 68 /// Like assert() but throws an exception instead of aborting the process. 69 #define Must(condition) Must2((condition), "check failed: " #condition) 70 71 /// Reports and swallows all exceptions to prevent compiler warnings and runtime 72 /// errors related to throwing class destructors. Should be used for most dtors. 73 #define SWALLOW_EXCEPTIONS(code) \ 74 try { \ 75 code \ 76 } catch (...) { \ 77 debugs(0, DBG_IMPORTANT, "BUG: ignoring exception;\n" << \ 78 " bug location: " << Here() << "\n" << \ 79 " ignored exception: " << CurrentException); \ 80 } 81 82 #endif /* SQUID__TEXTEXCEPTION_H */ 83 84