Exception: make source location print-out optional
[lttng-tools.git] / src / common / exception.hpp
CommitLineData
53cd1e22
JG
1/*
2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#ifndef LTTNG_EXCEPTION_H_
9#define LTTNG_EXCEPTION_H_
10
9f4d1ef3
JG
11#include <common/string-utils/c-string-view.hpp>
12
28f23191
JG
13#include <lttng/lttng-error.h>
14
53cd1e22 15#include <stdexcept>
28f23191 16#include <string>
53cd1e22
JG
17#include <system_error>
18
9f4d1ef3
JG
19#define LTTNG_SOURCE_LOCATION() lttng::source_location(__FILE__, __func__, __LINE__)
20
0038180d 21#define LTTNG_THROW_CTL(msg, error_code) \
9f4d1ef3 22 throw lttng::ctl::error(msg, error_code, LTTNG_SOURCE_LOCATION())
53cd1e22 23#define LTTNG_THROW_POSIX(msg, errno_code) \
9f4d1ef3
JG
24 throw lttng::posix_error(msg, errno_code, LTTNG_SOURCE_LOCATION())
25#define LTTNG_THROW_ERROR(msg) throw lttng::runtime_error(msg, LTTNG_SOURCE_LOCATION())
b6bbb1d6 26#define LTTNG_THROW_UNSUPPORTED_ERROR(msg) \
9f4d1ef3 27 throw lttng::unsupported_error(msg, LTTNG_SOURCE_LOCATION())
baac5795 28#define LTTNG_THROW_COMMUNICATION_ERROR(msg) \
9f4d1ef3
JG
29 throw lttng::communication_error(msg, LTTNG_SOURCE_LOCATION())
30#define LTTNG_THROW_PROTOCOL_ERROR(msg) throw lttng::protocol_error(msg, LTTNG_SOURCE_LOCATION())
baac5795 31#define LTTNG_THROW_INVALID_ARGUMENT_ERROR(msg) \
9f4d1ef3 32 throw lttng::invalid_argument_error(msg, LTTNG_SOURCE_LOCATION())
53cd1e22
JG
33
34namespace lttng {
9f4d1ef3
JG
35/**
36 * @class source_location
37 * @brief Represents the location in the source code where an exception was thrown.
38 *
39 * The source_location class captures the file name, function name, and line number
40 * of the source code where an exception occurs. This information is useful for
41 * debugging and logging purposes.
42 *
43 * @details
44 * This class provides:
45 * - The name of the source file (file_name).
46 * - The name of the function (function_name).
47 * - The line number in the source file (line_number).
48 *
49 * Example usage:
50 * @code
51 * try {
52 * // Code that may throw an exception.
53 * } catch (const lttng::runtime_error& ex) {
54 * // Handle the exception, possibly logging location information.
55 * ERR_FMT("{} [{}]", ex.what(), ex.source_location);
56 * }
57 * @endcode
58 */
59class source_location {
60public:
61 source_location(lttng::c_string_view file_name_,
62 lttng::c_string_view function_name_,
63 unsigned int line_number_) :
64 file_name(file_name_), function_name(function_name_), line_number(line_number_)
65 {
66 }
67
68 lttng::c_string_view file_name;
69 lttng::c_string_view function_name;
70 unsigned int line_number;
71};
72
73/**
74 * @class runtime_error
75 * @brief Base type for all LTTng exceptions.
76 *
77 * Exceptions in the project provide an error message (through the usual what() method), but that
78 * message may not include the whole context of the error. For example, it is not always desirable
79 * to include the source location in a user-facing message.
80 *
81 * As such, exception handlers should mind the type of the exception being thrown and consider
82 * what context is suitable to extract (e.g. some context may only be relevant at the DEBUG logging
83 * level, while the error message may be user-facing).
84 *
85 * Since 'what()' is marked as noexcept, derived classes should format their generic message during
86 * their construction and pass it to the runtime_error constructor.
87 */
baac5795
JG
88class runtime_error : public std::runtime_error {
89public:
9f4d1ef3
JG
90 runtime_error(const std::string& msg, const lttng::source_location& source_location);
91
92 lttng::source_location source_location;
baac5795 93};
53cd1e22 94
9f4d1ef3
JG
95/**
96 * @class unsupported_error
97 * @brief Represents an error for unsupported features.
98 *
99 * This error may occur due to the current configuration making a feature unavailable
100 * (e.g. when using an older kernel or tracer release).
101 */
102class unsupported_error : public lttng::runtime_error {
b6bbb1d6
JG
103public:
104 explicit unsupported_error(const std::string& msg,
9f4d1ef3 105 const lttng::source_location& source_location);
b6bbb1d6
JG
106};
107
53cd1e22 108namespace ctl {
9f4d1ef3
JG
109/**
110 * @class error
111 * @brief Wraps lttng_error_code errors for reporting through liblttng-ctl's interface.
112 *
113 * There is typically a better way to report errors than using this type of exception. However, it
114 * is sometimes useful to transition legacy code to use RAII facilities and exceptions without
115 * revisiting every caller.
116 */
baac5795 117class error : public runtime_error {
53cd1e22 118public:
0038180d
JG
119 explicit error(const std::string& msg,
120 lttng_error_code error_code,
9f4d1ef3 121 const lttng::source_location& source_location);
20f5a9ae
JG
122
123 lttng_error_code code() const noexcept
124 {
125 return _error_code;
126 }
53cd1e22
JG
127
128private:
20f5a9ae 129 const lttng_error_code _error_code;
53cd1e22
JG
130};
131} /* namespace ctl */
132
9f4d1ef3
JG
133/**
134 * @class posix_error
135 * @brief Wraps a POSIX system error, including the location where the error occurred.
136 */
137class posix_error : public std::system_error, lttng::runtime_error {
53cd1e22 138public:
baac5795 139 explicit posix_error(const std::string& msg,
9f4d1ef3
JG
140 unsigned int errno_code,
141 const lttng::source_location& source_location);
53cd1e22
JG
142};
143
9f4d1ef3
JG
144/**
145 * @class communication_error
146 * @brief Base class for communication errors between components.
147 */
148class communication_error : public lttng::runtime_error {
baac5795
JG
149public:
150 explicit communication_error(const std::string& msg,
9f4d1ef3 151 const lttng::source_location& source_location);
baac5795
JG
152};
153
9f4d1ef3
JG
154/**
155 * @class protocol_error
156 * @brief Base class for protocol layer communication errors (encoding or decoding problems).
157 */
baac5795
JG
158class protocol_error : public communication_error {
159public:
160 explicit protocol_error(const std::string& msg,
9f4d1ef3 161 const lttng::source_location& source_location);
baac5795
JG
162};
163
9f4d1ef3
JG
164/**
165 * @class invalid_argument_error
166 * @brief Represents an error for invalid arguments.
167 */
168class invalid_argument_error : public lttng::runtime_error {
aeeb48c6 169public:
baac5795 170 explicit invalid_argument_error(const std::string& msg,
9f4d1ef3 171 const lttng::source_location& source_location);
aeeb48c6
JG
172};
173
9f4d1ef3
JG
174} /* namespace lttng */
175
176/*
177 * Specialize fmt::formatter for lttng::source_location
178 *
179 * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace,
180 * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
181 */
182namespace fmt {
183template <>
184struct formatter<lttng::source_location> : formatter<std::string> {
185 template <typename FormatContextType>
186 typename FormatContextType::iterator format(const lttng::source_location& location,
187 FormatContextType& ctx)
188 {
189 return format_to(ctx.out(),
190 "{}() {}:{}",
191 location.function_name.data(),
192 location.file_name.data(),
193 location.line_number);
194 }
195};
196} /* namespace fmt */
53cd1e22
JG
197
198#endif /* LTTNG_EXCEPTION_H_ */
This page took 0.047934 seconds and 4 git commands to generate.