LCOV - code coverage report
Current view: top level - include/base - MooseError.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 88 89 98.9 %
Date: 2026-05-29 20:35:17 Functions: 1346 3079 43.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "Moose.h"
      13             : #include "MooseException.h"
      14             : #include "libmesh/threads.h"
      15             : 
      16             : #include "libmesh/print_trace.h"
      17             : #include "libmesh/libmesh_common.h"
      18             : 
      19             : // C++ includes
      20             : #include <cstdlib>
      21             : #include <tuple>
      22             : #include <type_traits>
      23             : 
      24             : // Used in numerous downstream classes without 'libMesh::' prefix
      25             : using libMesh::demangle;
      26             : 
      27             : namespace MetaPhysicL
      28             : {
      29             : class LogicError;
      30             : }
      31             : 
      32             : namespace hit
      33             : {
      34             : class Node;
      35             : }
      36             : 
      37             : // this function allows streaming tuples to ostreams
      38             : template <size_t n, typename... T>
      39             : void
      40             : print_tuple(std::ostream & os, const std::tuple<T...> & tup)
      41             : {
      42             :   if constexpr (n < sizeof...(T))
      43             :   {
      44             :     if (n != 0)
      45             :       os << ", ";
      46             :     os << std::get<n>(tup);
      47             :     print_tuple<n + 1>(os, tup);
      48             :   }
      49             : }
      50             : template <typename... T>
      51             : std::ostream &
      52             : operator<<(std::ostream & os, const std::tuple<T...> & tup)
      53             : {
      54             :   os << "[";
      55             :   print_tuple<0>(os, tup);
      56             :   return os << "]";
      57             : }
      58             : 
      59             : #define mooseDoOnce(do_this)                                                                       \
      60             :   do                                                                                               \
      61             :   {                                                                                                \
      62             :     static bool did_this_already = false;                                                          \
      63             :     if (Moose::show_multiple || !did_this_already)                                                 \
      64             :     {                                                                                              \
      65             :       did_this_already = true;                                                                     \
      66             :       do_this;                                                                                     \
      67             :     }                                                                                              \
      68             :   } while (0)
      69             : 
      70             : #define mooseCheckMPIErr(err)                                                                      \
      71             :   do                                                                                               \
      72             :   {                                                                                                \
      73             :     if (err != MPI_SUCCESS)                                                                        \
      74             :       moose::internal::mooseErrorRaw("");                                                          \
      75             :   } while (0)
      76             : 
      77             : #define mooseException(...)                                                                        \
      78             :   do                                                                                               \
      79             :   {                                                                                                \
      80             :     throw MooseException(__VA_ARGS__);                                                             \
      81             :   } while (0)
      82             : 
      83             : #ifdef NDEBUG
      84             : #define mooseAssert(asserted, msg) ((void)0)
      85             : #else
      86             : #define mooseAssert(asserted, msg)                                                                 \
      87             :   do                                                                                               \
      88             :   {                                                                                                \
      89             :     if (!(asserted))                                                                               \
      90             :     {                                                                                              \
      91             :       std::ostringstream _assert_oss_;                                                             \
      92             :       _assert_oss_ << COLOR_RED << "\n\nAssertion `" #asserted "' failed\n"                        \
      93             :                    << msg << "\nat " << __FILE__ << ", line " << __LINE__ << COLOR_DEFAULT         \
      94             :                    << std::endl;                                                                   \
      95             :       if (Moose::_throw_on_error)                                                                  \
      96             :         throw std::runtime_error(_assert_oss_.str());                                              \
      97             :       else                                                                                         \
      98             :       {                                                                                            \
      99             :         Moose::err << _assert_oss_.str() << std::flush;                                            \
     100             :         moose::internal::mooseErrorRaw("");                                                        \
     101             :       }                                                                                            \
     102             :     }                                                                                              \
     103             :   } while (0)
     104             : #endif
     105             : 
     106             : template <typename... Args>
     107             : [[noreturn]] void mooseError(Args &&... args);
     108             : 
     109             : /**
     110             :  * Exception to be thrown whenever we have _throw_on_error set and a
     111             :  * mooseError() is emitted.
     112             :  *
     113             :  * Enables adding the context of the hit node from the location in input
     114             :  * associated with the error, which can be used in the MooseServer to
     115             :  * produce diagnostics without parsing messages.
     116             :  */
     117             : class MooseRuntimeError : public std::runtime_error
     118             : {
     119             : public:
     120         799 :   MooseRuntimeError(const std::string & message, const hit::Node * const node)
     121         799 :     : runtime_error(message), _node(node)
     122             :   {
     123         799 :   }
     124             : 
     125             :   /// Get the associated hit node, if any
     126          10 :   const hit::Node * getNode() const { return _node; }
     127             : 
     128             : private:
     129             :   /// The associated hit node, if any
     130             :   const hit::Node * const _node;
     131             : };
     132             : 
     133             : class MooseVariableFieldBase;
     134             : 
     135             : namespace moose
     136             : {
     137             : 
     138             : namespace internal
     139             : {
     140             : inline libMesh::Threads::spin_mutex moose_stream_lock;
     141             : 
     142             : /// Builds and returns a string of the form:
     143             : ///
     144             : ///     [var1-elemtype],ORDER[var1-order] != [var2-elemtype],ORDER[var2-order]
     145             : ///
     146             : /// This is a convenience function to be used when error messages (especially with paramError)
     147             : /// need to report that variable types are incompatible (e.g. with residual save-in).
     148             : std::string incompatVarMsg(MooseVariableFieldBase & var1, MooseVariableFieldBase & var2);
     149             : 
     150             : /**
     151             :  * Format a message for output with a title
     152             :  * @param msg The message to print
     153             :  * @param title The title that will go on a line before the message
     154             :  * @param color The color to print the message in
     155             :  * @return The formatted message
     156             :  */
     157             : std::string
     158             : mooseMsgFmt(const std::string & msg, const std::string & title, const std::string & color);
     159             : 
     160             : /**
     161             :  * Format a message for output without a title
     162             :  * @param msg The message to print
     163             :  * @param color The color to print the message in
     164             :  * @return The formatted message
     165             :  */
     166             : std::string mooseMsgFmt(const std::string & msg, const std::string & color);
     167             : 
     168             : /**
     169             :  * Main callback for emitting a moose error.
     170             :  * @param msg The error message
     171             :  * @param prefix Optional prefix to add to every line of the error (for multiapp prefixes)
     172             :  * @param node Optional HIT node to associate with the error, adding file path context
     173             :  * @param show_trace Whether or not to show a stack trace, defaults to true
     174             :  */
     175             : [[noreturn]] void mooseErrorRaw(std::string msg,
     176             :                                 const std::string & prefix = "",
     177             :                                 const hit::Node * node = nullptr,
     178             :                                 const bool show_trace = true);
     179             : 
     180             : /**
     181             :  * All of the following are not meant to be called directly - they are called by the normal macros
     182             :  * (mooseError(), etc.) down below
     183             :  * @{
     184             :  */
     185             : void mooseStreamAll(std::ostringstream & ss);
     186             : 
     187             : template <typename T, typename... Args>
     188             : void
     189       60422 : mooseStreamAll(std::ostringstream & ss, T && val, Args &&... args)
     190             : {
     191       60422 :   ss << val;
     192       60422 :   mooseStreamAll(ss, std::forward<Args>(args)...);
     193       60422 : }
     194             : 
     195             : template <typename S, typename... Args>
     196             : void
     197        3652 : mooseWarningStream(S & oss, Args &&... args)
     198             : {
     199        3652 :   if (Moose::_warnings_are_errors)
     200         152 :     mooseError(std::forward<Args>(args)...);
     201             : 
     202        3500 :   std::ostringstream ss;
     203        3500 :   mooseStreamAll(ss, args...);
     204       10500 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     205        3500 :   if (Moose::_throw_on_warning)
     206          20 :     throw std::runtime_error(msg);
     207             : 
     208             :   {
     209        3480 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     210        3480 :     oss << msg << std::flush;
     211        3480 :   }
     212        3520 : }
     213             : 
     214             : template <typename S, typename... Args>
     215             : void
     216          44 : mooseUnusedStream(S & oss, Args &&... args)
     217             : {
     218          44 :   std::ostringstream ss;
     219          44 :   mooseStreamAll(ss, args...);
     220         132 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     221          44 :   if (Moose::_throw_on_warning)
     222           0 :     throw std::runtime_error(msg);
     223             : 
     224             :   {
     225          44 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     226          44 :     oss << msg << std::flush;
     227          44 :   }
     228          44 : }
     229             : 
     230             : template <typename S, typename... Args>
     231             : void
     232       13632 : mooseInfoStreamRepeated(S & oss, Args &&... args)
     233             : {
     234       13632 :   std::ostringstream ss;
     235       13632 :   mooseStreamAll(ss, args...);
     236       40896 :   std::string msg = mooseMsgFmt(ss.str(), "*** Info ***", COLOR_CYAN);
     237             :   {
     238       13632 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     239       13632 :     oss << msg << std::flush;
     240       13632 :   }
     241       13632 : }
     242             : 
     243             : template <typename S, typename... Args>
     244             : void
     245       12670 : mooseInfoStream(S & oss, Args &&... args)
     246             : {
     247       12670 :   mooseDoOnce(mooseInfoStreamRepeated(oss, args...););
     248       12670 : }
     249             : 
     250             : template <typename S, typename... Args>
     251             : void
     252        7796 : mooseDeprecatedStream(
     253             :     S & oss, const bool expired, const bool print_title, const bool show_trace, Args &&... args)
     254             : {
     255        7796 :   if (Moose::_deprecated_is_error)
     256          13 :     mooseError("\n\nDeprecated code:\n", std::forward<Args>(args)...);
     257             : 
     258        7783 :   std::ostringstream ss;
     259        7783 :   mooseStreamAll(ss, args...);
     260             : 
     261        7783 :   const auto color = expired ? COLOR_RED : COLOR_YELLOW;
     262       31132 :   std::string msg = print_title ? mooseMsgFmt(ss.str(), "*** Deprecation Warning ***", color)
     263             :                                 : mooseMsgFmt(ss.str(), color);
     264        7783 :   oss << msg;
     265        7783 :   ss.str("");
     266        7783 :   if (show_trace)
     267             :   {
     268        5017 :     if (libMesh::global_n_processors() == 1)
     269        2985 :       libMesh::print_trace(ss);
     270             :     else
     271        2032 :       libMesh::write_traceout();
     272             :     {
     273        5017 :       libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     274        5017 :       oss << ss.str() << std::endl;
     275        5017 :     };
     276             :   };
     277        7783 : }
     278             : /**
     279             :  * @}
     280             :  */
     281             : 
     282             : /**
     283             :  * Formats a documented error. A documented error is an error that has
     284             :  * an issue associated with it.
     285             :  *
     286             :  * The repository name \p repo_name links a named repository to a URL
     287             :  * and should be registered at the application level with registerRepository().
     288             :  * See Moose.C for an example of the "moose" repository registration.
     289             :  *
     290             :  * @param repo_name The repository name where the issue resides
     291             :  * @param issue_num The number of the issue
     292             :  * @param msg The specific error message
     293             :  */
     294             : std::string formatMooseDocumentedError(const std::string & repo_name,
     295             :                                        const unsigned int issue_num,
     296             :                                        const std::string & msg);
     297             : } // namespace internal
     298             : 
     299             : /**
     300             :  * emit a relatively clear error message when we catch a MetaPhysicL logic error
     301             :  */
     302             : void translateMetaPhysicLError(const MetaPhysicL::LogicError &);
     303             : 
     304             : } // namespace moose
     305             : 
     306             : /// Emit an error message with the given stringified, concatenated args and
     307             : /// terminate the application.  Inside static functions, you will need to
     308             : /// explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     309             : template <typename... Args>
     310             : [[noreturn]] void
     311        1463 : mooseError(Args &&... args)
     312             : {
     313        1463 :   std::ostringstream oss;
     314        1463 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     315        2757 :   moose::internal::mooseErrorRaw(oss.str());
     316         647 : }
     317             : 
     318             : /**
     319             :  * Emit a documented error message with the given stringified, concatenated args
     320             :  * and terminate the application.  Inside static functions, you will need to
     321             :  * explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     322             :  *
     323             :  * Here, a documented error message is one with an associated issue. See
     324             :  * formatMooseDocumentedError for more information.
     325             :  *
     326             :  * @param repo_name The repository name where the issue resides
     327             :  * @param issue_num The number of the issue
     328             :  * @param args The error message to stringify
     329             :  **/
     330             : template <typename... Args>
     331             : [[noreturn]] void
     332           2 : mooseDocumentedError(const std::string & repo_name, const unsigned int issue_num, Args &&... args)
     333             : {
     334           2 :   std::ostringstream oss;
     335           2 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     336           8 :   moose::internal::mooseErrorRaw(
     337             :       moose::internal::formatMooseDocumentedError(repo_name, issue_num, oss.str()));
     338           2 : }
     339             : 
     340             : /// Emit a warning message with the given stringified, concatenated args.
     341             : /// Inside static functions, you will need to explicitly scope your
     342             : /// mooseWarning call - i.e. do "::mooseWarning(arg1, ...);".
     343             : template <typename... Args>
     344             : void
     345        1077 : mooseWarning(Args &&... args)
     346             : {
     347        1077 :   moose::internal::mooseWarningStream(Moose::out, std::forward<Args>(args)...);
     348        1044 : }
     349             : 
     350             : /// Warning message used to notify the users of unused parts of their input files
     351             : /// Really used internally by the parser and shouldn't really be called elsewhere
     352             : template <typename... Args>
     353             : void
     354          44 : mooseUnused(Args &&... args)
     355             : {
     356          44 :   moose::internal::mooseUnusedStream(Moose::out, std::forward<Args>(args)...);
     357          44 : }
     358             : 
     359             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     360             : /// Will include a stack trace; use mooseDeprecatedNoTrace to exclude the trace.
     361             : template <typename... Args>
     362             : void
     363        3686 : mooseDeprecated(Args &&... args)
     364             : {
     365        3686 :   moose::internal::mooseDeprecatedStream(
     366             :       Moose::out, false, true, true, std::forward<Args>(args)...);
     367        3684 : }
     368             : 
     369             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     370             : /// Will not include a stack trace; use mooseDeprecated to include the trace.
     371             : template <typename... Args>
     372             : void
     373         676 : mooseDeprecatedNoTrace(Args &&... args)
     374             : {
     375         676 :   moose::internal::mooseDeprecatedStream(
     376             :       Moose::out, false, true, false, std::forward<Args>(args)...);
     377         676 : }
     378             : 
     379             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     380             : /// Will include a stack trace; use mooseDeprecationExpiredNoTrace to exclude the trace.
     381             : template <typename... Args>
     382             : void
     383             : mooseDeprecationExpired(Args &&... args)
     384             : {
     385             :   moose::internal::mooseDeprecatedStream(Moose::out, true, true, true, std::forward<Args>(args)...);
     386             : }
     387             : 
     388             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     389             : /// Will not include a stack trace; use mooseDeprecationExpired to include the trace.
     390             : template <typename... Args>
     391             : void
     392        1350 : mooseDeprecationExpiredNoTrace(Args &&... args)
     393             : {
     394        1350 :   moose::internal::mooseDeprecatedStream(
     395             :       Moose::out, true, true, false, std::forward<Args>(args)...);
     396        1347 : }
     397             : 
     398             : /// Emit an informational message with the given stringified, concatenated args.
     399             : template <typename... Args>
     400             : void
     401         507 : mooseInfo(Args &&... args)
     402             : {
     403         507 :   moose::internal::mooseInfoStream(Moose::out, std::forward<Args>(args)...);
     404         507 : }
     405             : 
     406             : /// Emit an informational message with the given stringified, concatenated args.
     407             : template <typename... Args>
     408             : void
     409        3711 : mooseInfoRepeated(Args &&... args)
     410             : {
     411        3711 :   moose::internal::mooseInfoStreamRepeated(Moose::out, std::forward<Args>(args)...);
     412        3711 : }

Generated by: LCOV version 1.14