]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/TextException.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / base / TextException.cc
CommitLineData
bbc27441 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
bbc27441
AJ
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
582c2af2 9#include "squid.h"
3d93a84d 10#include "base/TextException.h"
e99fa721 11#include "sbuf/SBuf.h"
774c051c 12
ebaabe74
AR
13#include <iostream>
14#include <sstream>
15#include <unordered_map>
77442705 16
ebaabe74
AR
17/// a standard CoW string; avoids noise and circular dependencies of SBuf
18typedef std::runtime_error WhatString;
77442705 19
ebaabe74
AR
20/// a collection of strings indexed by pointers to their creator objects
21typedef std::unordered_multimap<const void*, WhatString> WhatStrings;
22
23/// requested what() strings of alive TextException objects
24static WhatStrings *WhatStrings_ = nullptr;
774c051c 25
ebaabe74
AR
26TextException::TextException(SBuf message, const SourceLocation &location):
27 TextException(message.c_str(), location)
e99fa721
EB
28{}
29
0a8bbeeb 30TextException::~TextException() throw()
774c051c 31{
ebaabe74
AR
32 if (WhatStrings_)
33 WhatStrings_->erase(this); // there only if what() has been called
77442705
AJ
34}
35
ebaabe74
AR
36std::ostream &
37TextException::print(std::ostream &os) const
77442705 38{
ccfbe8f4 39 os << std::runtime_error::what() <<
77b1029d 40 Debug::Extra << "exception location: " << where;
ccfbe8f4 41 // TODO: ...error_detail: " << (ERR_DETAIL_EXCEPTION_START+id());
ebaabe74 42 return os;
774c051c 43}
44
ebaabe74
AR
45const char *
46TextException::what() const throw()
0a8bbeeb 47{
ebaabe74
AR
48 std::ostringstream os;
49 print(os);
50 const WhatString result(os.str());
0a8bbeeb 51
ebaabe74
AR
52 // extend result.c_str() lifetime to this object lifetime
53 if (!WhatStrings_)
54 WhatStrings_ = new WhatStrings;
55 // *this could change, but we must preserve old results for they may be used
56 WhatStrings_->emplace(std::make_pair(this, result));
64b66b76 57
ebaabe74 58 return result.what();
64b66b76
CT
59}
60
83b053a0
CT
61std::ostream &
62operator <<(std::ostream &os, const TextException &ex)
63{
64 ex.print(os);
65 return os;
66}
67
ebaabe74
AR
68std::ostream &
69CurrentException(std::ostream &os)
774c051c 70{
ebaabe74
AR
71 if (std::current_exception()) {
72 try {
73 throw; // re-throw to recognize the exception type
74 }
83b053a0
CT
75 catch (const TextException &ex) {
76 os << ex; // optimization: this is a lot cheaper than what() below
77 }
ebaabe74
AR
78 catch (const std::exception &ex) {
79 os << ex.what();
80 }
81 catch (...) {
82 os << "[unknown exception type]";
83 }
774c051c 84 } else {
ebaabe74 85 os << "[no active exception]";
774c051c 86 }
ebaabe74 87 return os;
774c051c 88}
f53969cc 89