TextException.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 #include "squid.h"
10 #include "base/TextException.h"
11 #include "sbuf/SBuf.h"
12 
13 #include <iostream>
14 #include <sstream>
15 #include <unordered_map>
16 
18 typedef std::runtime_error WhatString;
19 
21 typedef std::unordered_multimap<const void*, WhatString> WhatStrings;
22 
24 static WhatStrings *WhatStrings_ = nullptr;
25 
27  TextException(message.c_str(), location)
28 {}
29 
31 {
32  if (WhatStrings_)
33  WhatStrings_->erase(this); // there only if what() has been called
34 }
35 
36 std::ostream &
37 TextException::print(std::ostream &os) const
38 {
39  os << std::runtime_error::what() <<
40  Debug::Extra << "exception location: " << where;
41  // TODO: ...error_detail: " << (ERR_DETAIL_EXCEPTION_START+id());
42  return os;
43 }
44 
45 const char *
46 TextException::what() const throw()
47 {
48  std::ostringstream os;
49  print(os);
50  const WhatString result(os.str());
51 
52  // extend result.c_str() lifetime to this object lifetime
53  if (!WhatStrings_)
55  // *this could change, but we must preserve old results for they may be used
56  WhatStrings_->emplace(std::make_pair(this, result));
57 
58  return result.what();
59 }
60 
61 std::ostream &
62 operator <<(std::ostream &os, const TextException &ex)
63 {
64  ex.print(os);
65  return os;
66 }
67 
69 static std::ostream &
70 CurrentException_(std::ostream &os)
71 {
72  try {
73  throw; // re-throw to recognize the exception type
74  }
75  catch (const TextException &ex) {
76  os << ex; // optimization: this is a lot cheaper than what() below
77  }
78  catch (const std::exception &ex) {
79  os << ex.what();
80  }
81  catch (...) {
82  os << "[unknown exception type]";
83  }
84  return os;
85 }
86 
87 std::ostream &
88 CurrentException(std::ostream &os)
89 {
90  if (std::current_exception()) {
91  os << CurrentException_;
92  } else {
93  os << "[no active exception]";
94  }
95  return os;
96 }
97 
98 std::ostream &
99 CurrentExceptionExtra(std::ostream &os)
100 {
101  if (std::current_exception())
102  os << Debug::Extra << "exception: " << CurrentException_;
103  return os;
104 }
105 
~TextException() override
std::ostream & operator<<(std::ostream &os, const TextException &ex)
efficiently prints TextException
Definition: SBuf.h:93
TextException(const char *message, const SourceLocation &location)
Definition: TextException.h:24
std::unordered_multimap< const void *, WhatString > WhatStrings
a collection of strings indexed by pointers to their creator objects
std::ostream & CurrentExceptionExtra(std::ostream &os)
SourceLocation where
code location related to the exception; usually the thrower location
Definition: TextException.h:46
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
static std::ostream & Extra(std::ostream &)
Definition: debug.cc:1316
a source code location that is cheap to create, copy, and store
Definition: Here.h:29
const char * what() const override
an std::runtime_error with thrower location info
Definition: TextException.h:20
static WhatStrings * WhatStrings_
requested what() strings of alive TextException objects
std::runtime_error WhatString
a standard CoW string; avoids noise and circular dependencies of SBuf
std::ostream & print(std::ostream &) const
dumps the exception text into the stream
static std::ostream & CurrentException_(std::ostream &os)
prints the current exception (which presence has been verified by the caller)

 

Introduction

Documentation

Support

Miscellaneous