Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:38

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #pragma once
0006 
0007 #include <JANA/Utils/JBacktrace.h>
0008 #include <sstream> // This is only here in order to not break halld_recon
0009 #include <string>
0010 
0011 /// JException is a data object which attaches JANA-specific context information to a generic exception.
0012 /// As it unwinds the call stack, different exception handlers may add or change information as they see fit.
0013 /// It does not use getters and setters, because they are not needed, because there is no invariant.
0014 struct JException : public std::exception {
0015 public:
0016 
0017     /// Basic constructor
0018     explicit JException(std::string message = "Unknown exception") : message(std::move(message)) {
0019         backtrace.Capture(2);
0020     }
0021 
0022     virtual ~JException() = default;
0023 
0024 
0025     /// Constructor with printf-style formatting
0026     template<typename... Args>
0027     explicit JException(std::string message, Args... args);
0028 
0029 
0030     std::string GetMessage() {
0031         return message;
0032     }
0033 
0034     std::string GetStackTrace() {
0035         return backtrace.ToString();
0036     }
0037 
0038     const char* what() const noexcept {
0039         return message.c_str();
0040     }
0041 
0042     /// Convenience method for formatting complete error data
0043     inline friend std::ostream& operator<<(std::ostream& os, JException const& ex) {
0044         os << "JException" << std::endl;
0045         if (ex.exception_type.length() != 0) {
0046             os << "  Type:     " << ex.exception_type << std::endl;
0047         }
0048         if (ex.message.length() != 0) {
0049             os << "  Message:  " << ex.message << std::endl;
0050         }
0051         if (ex.function_name.length() != 0) {
0052             os << "  Function: " << ex.function_name << std::endl;
0053         }
0054         if (ex.type_name.length() != 0) {
0055             os << "  Class:    " << ex.type_name << std::endl;
0056         }
0057         if (ex.instance_name.length() != 0) {
0058             os << "  Instance: " << ex.instance_name << std::endl;
0059         }
0060         if (ex.plugin_name.length() != 0) {
0061             os << "  Plugin:   " << ex.plugin_name << std::endl;
0062         }
0063         if (ex.show_stacktrace) {
0064             ex.backtrace.WaitForCapture();
0065             ex.backtrace.ToString();
0066             os << "  Backtrace:" << std::endl << std::endl << ex.backtrace.ToString();
0067         }
0068         return os;
0069     }
0070 
0071     std::string exception_type;
0072     std::string message;
0073     std::string plugin_name;
0074     std::string type_name;
0075     std::string function_name;
0076     std::string instance_name;
0077     JBacktrace backtrace;
0078     std::exception_ptr nested_exception;
0079     bool show_stacktrace=true;
0080 
0081 };
0082 
0083 
0084 /// Constructor with convenient printf-style formatting.
0085 /// Uses variadic templates (although it is slightly overkill) because variadic functions are frowned on now.
0086 template<typename... Args>
0087 JException::JException(std::string format_str, Args... args) {
0088     char cmess[1024];
0089     snprintf(cmess, 1024, format_str.c_str(), args...);
0090     message = cmess;
0091     backtrace.Capture(2);
0092 }
0093 
0094