Add logging to internal error
Internal error call sites are propagated through the code, and might be
triggered multiple times in the course of a request, which makes them
difficult to track the source of.
This commit changes the internalError() method to include a print of
which invocation within bmcweb triggered the error, using c++20s
std::source_location mechanism.
Note:
clang-13 still doesn't implement std::source_location, so this commit
pulls source_location.hpp from lg2 to be able to support all compilers.
Tested:
Loaded in qemu, and added an internalError() call into systems.hpp for
the /redfish/v1/Systems handler. Observed that
[CRITICAL "error_messages.cpp":234] Internal Error
../../../../../../workspace/sources/bmcweb/redfish-core/include/../lib/systems.hpp(2820:40)
`redfish::requestRoutesSystemsCollection(App&)::<lambda(const
crow::Request&, const std::shared_ptr<bmcweb::AsyncResp>&)>`:
Got printed to the bmcweb logs.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ic1b4240422445357bc87404de814ad14f86b9edf
diff --git a/include/source_location.hpp b/include/source_location.hpp
new file mode 100644
index 0000000..9880752
--- /dev/null
+++ b/include/source_location.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+// As of clang-12, clang still doesn't support std::source_location, which
+// means that clang-tidy also doesn't support std::source_location.
+// Inside the libstdc++ implementation of <source_location> is this check of
+// __builtin_source_location to determine if the compiler supports the
+// necessary bits for std::source_location, and if not the header ends up doing
+// nothing. Use this same builtin-check to detect when we're running under
+// an "older" clang and fallback to std::experimental::source_location instead.
+
+#if __has_builtin(__builtin_source_location)
+#include <source_location>
+
+namespace bmcweb
+{
+using source_location = std::source_location;
+}
+
+#else
+#include <experimental/source_location>
+
+namespace bmcweb
+{
+using source_location = std::experimental::source_location;
+}
+
+#endif
diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index 3d11cc4..c9a919a 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -17,6 +17,7 @@
#include "http_response.hpp"
#include <nlohmann/json.hpp>
+#include <source_location.hpp>
namespace redfish
{
@@ -88,7 +89,8 @@
* @returns Message InternalError formatted to JSON */
nlohmann::json internalError();
-void internalError(crow::Response& res);
+void internalError(crow::Response& res, const bmcweb::source_location location =
+ bmcweb::source_location::current());
/**
* @brief Formats UnrecognizedRequestBody message into JSON
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 9c28e8f..cb4d69c 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -229,8 +229,11 @@
"consider resetting the service."}};
}
-void internalError(crow::Response& res)
+void internalError(crow::Response& res, const bmcweb::source_location location)
{
+ BMCWEB_LOG_CRITICAL << "Internal Error " << location.file_name() << "("
+ << location.line() << ":" << location.column() << ") `"
+ << location.function_name() << "`: ";
res.result(boost::beast::http::status::internal_server_error);
addMessageToErrorJson(res.jsonValue, internalError());
}