LCOV - code coverage report
Current view: top level - include/base - MooseError.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33380 (547b29) with base 8581c3 Lines: 90 92 97.8 %
Date: 2026-07-20 19:36:28 Functions: 1380 3149 43.8 %
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         825 :   MooseRuntimeError(const std::string & message, const hit::Node * const node)
     121         825 :     : runtime_error(message), _node(node)
     122             :   {
     123         825 :   }
     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       60779 : mooseStreamAll(std::ostringstream & ss, T && val, Args &&... args)
     190             : {
     191       60779 :   ss << val;
     192       60779 :   mooseStreamAll(ss, std::forward<Args>(args)...);
     193       60779 : }
     194             : 
     195             : template <typename S, typename... Args>
     196             : void
     197        3650 : mooseWarningStream(S & oss, Args &&... args)
     198             : {
     199        3650 :   if (Moose::_warnings_are_errors)
     200         151 :     mooseError(std::forward<Args>(args)...);
     201             : 
     202        3499 :   std::ostringstream ss;
     203        3499 :   mooseStreamAll(ss, args...);
     204       10497 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     205        3499 :   if (Moose::_throw_on_warning)
     206          20 :     throw std::runtime_error(msg);
     207             : 
     208             :   {
     209        3479 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     210        3479 :     oss << msg << std::flush;
     211        3479 :   }
     212        3519 : }
     213             : 
     214             : template <typename S, typename... Args>
     215             : void
     216          51 : mooseUnusedStream(S & oss, Args &&... args)
     217             : {
     218          51 :   std::ostringstream ss;
     219          51 :   mooseStreamAll(ss, args...);
     220         153 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     221          51 :   if (Moose::_throw_on_warning)
     222           0 :     throw std::runtime_error(msg);
     223             : 
     224             :   {
     225          51 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     226          51 :     oss << msg << std::flush;
     227          51 :   }
     228          51 : }
     229             : 
     230             : template <typename S, typename... Args>
     231             : void
     232       13767 : mooseInfoStreamRepeated(S & oss, Args &&... args)
     233             : {
     234       13767 :   if (Moose::_suppress_info)
     235          54 :     return;
     236             : 
     237       13713 :   std::ostringstream ss;
     238       13713 :   mooseStreamAll(ss, args...);
     239       41139 :   std::string msg = mooseMsgFmt(ss.str(), "*** Info ***", COLOR_CYAN);
     240             :   {
     241       13713 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     242       13713 :     oss << msg << std::flush;
     243       13713 :   }
     244       13713 : }
     245             : 
     246             : template <typename S, typename... Args>
     247             : void
     248       12436 : mooseInfoStream(S & oss, Args &&... args)
     249             : {
     250       12436 :   if (Moose::_suppress_info)
     251           0 :     return;
     252             : 
     253       12436 :   mooseDoOnce(mooseInfoStreamRepeated(oss, args...););
     254             : }
     255             : 
     256             : template <typename S, typename... Args>
     257             : void
     258        7826 : mooseDeprecatedStream(
     259             :     S & oss, const bool expired, const bool print_title, const bool show_trace, Args &&... args)
     260             : {
     261        7826 :   if (Moose::_deprecated_is_error)
     262          13 :     mooseError("\n\nDeprecated code:\n", std::forward<Args>(args)...);
     263             : 
     264        7813 :   std::ostringstream ss;
     265        7813 :   mooseStreamAll(ss, args...);
     266             : 
     267        7813 :   const auto color = expired ? COLOR_RED : COLOR_YELLOW;
     268       31252 :   std::string msg = print_title ? mooseMsgFmt(ss.str(), "*** Deprecation Warning ***", color)
     269             :                                 : mooseMsgFmt(ss.str(), color);
     270        7813 :   oss << msg;
     271        7813 :   ss.str("");
     272        7813 :   if (show_trace)
     273             :   {
     274        5047 :     if (libMesh::global_n_processors() == 1)
     275        3009 :       libMesh::print_trace(ss);
     276             :     else
     277        2038 :       libMesh::write_traceout();
     278             :     {
     279        5047 :       libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     280        5047 :       oss << ss.str() << std::endl;
     281        5047 :     };
     282             :   };
     283        7813 : }
     284             : /**
     285             :  * @}
     286             :  */
     287             : 
     288             : /**
     289             :  * Formats a documented error. A documented error is an error that has
     290             :  * an issue associated with it.
     291             :  *
     292             :  * The repository name \p repo_name links a named repository to a URL
     293             :  * and should be registered at the application level with registerRepository().
     294             :  * See Moose.C for an example of the "moose" repository registration.
     295             :  *
     296             :  * @param repo_name The repository name where the issue resides
     297             :  * @param issue_num The number of the issue
     298             :  * @param msg The specific error message
     299             :  */
     300             : std::string formatMooseDocumentedError(const std::string & repo_name,
     301             :                                        const unsigned int issue_num,
     302             :                                        const std::string & msg);
     303             : } // namespace internal
     304             : 
     305             : /**
     306             :  * emit a relatively clear error message when we catch a MetaPhysicL logic error
     307             :  */
     308             : void translateMetaPhysicLError(const MetaPhysicL::LogicError &);
     309             : 
     310             : } // namespace moose
     311             : 
     312             : /// Emit an error message with the given stringified, concatenated args and
     313             : /// terminate the application.  Inside static functions, you will need to
     314             : /// explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     315             : template <typename... Args>
     316             : [[noreturn]] void
     317        1492 : mooseError(Args &&... args)
     318             : {
     319        1492 :   std::ostringstream oss;
     320        1492 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     321        2834 :   moose::internal::mooseErrorRaw(oss.str());
     322         671 : }
     323             : 
     324             : /**
     325             :  * Emit a documented error message with the given stringified, concatenated args
     326             :  * and terminate the application.  Inside static functions, you will need to
     327             :  * explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     328             :  *
     329             :  * Here, a documented error message is one with an associated issue. See
     330             :  * formatMooseDocumentedError for more information.
     331             :  *
     332             :  * @param repo_name The repository name where the issue resides
     333             :  * @param issue_num The number of the issue
     334             :  * @param args The error message to stringify
     335             :  **/
     336             : template <typename... Args>
     337             : [[noreturn]] void
     338           2 : mooseDocumentedError(const std::string & repo_name, const unsigned int issue_num, Args &&... args)
     339             : {
     340           2 :   std::ostringstream oss;
     341           2 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     342           8 :   moose::internal::mooseErrorRaw(
     343             :       moose::internal::formatMooseDocumentedError(repo_name, issue_num, oss.str()));
     344           2 : }
     345             : 
     346             : /// Emit a warning message with the given stringified, concatenated args.
     347             : /// Inside static functions, you will need to explicitly scope your
     348             : /// mooseWarning call - i.e. do "::mooseWarning(arg1, ...);".
     349             : template <typename... Args>
     350             : void
     351        1077 : mooseWarning(Args &&... args)
     352             : {
     353        1077 :   moose::internal::mooseWarningStream(Moose::out, std::forward<Args>(args)...);
     354        1044 : }
     355             : 
     356             : /// Warning message used to notify the users of unused parts of their input files
     357             : /// Really used internally by the parser and shouldn't really be called elsewhere
     358             : template <typename... Args>
     359             : void
     360          51 : mooseUnused(Args &&... args)
     361             : {
     362          51 :   moose::internal::mooseUnusedStream(Moose::out, std::forward<Args>(args)...);
     363          51 : }
     364             : 
     365             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     366             : /// Will include a stack trace; use mooseDeprecatedNoTrace to exclude the trace.
     367             : template <typename... Args>
     368             : void
     369        3689 : mooseDeprecated(Args &&... args)
     370             : {
     371        3689 :   moose::internal::mooseDeprecatedStream(
     372             :       Moose::out, false, true, true, std::forward<Args>(args)...);
     373        3687 : }
     374             : 
     375             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     376             : /// Will not include a stack trace; use mooseDeprecated to include the trace.
     377             : template <typename... Args>
     378             : void
     379         550 : mooseDeprecatedNoTrace(Args &&... args)
     380             : {
     381         550 :   moose::internal::mooseDeprecatedStream(
     382             :       Moose::out, false, true, false, std::forward<Args>(args)...);
     383         550 : }
     384             : 
     385             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     386             : /// Will include a stack trace; use mooseDeprecationExpiredNoTrace to exclude the trace.
     387             : template <typename... Args>
     388             : void
     389             : mooseDeprecationExpired(Args &&... args)
     390             : {
     391             :   moose::internal::mooseDeprecatedStream(Moose::out, true, true, true, std::forward<Args>(args)...);
     392             : }
     393             : 
     394             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     395             : /// Will not include a stack trace; use mooseDeprecationExpired to include the trace.
     396             : template <typename... Args>
     397             : void
     398        1476 : mooseDeprecationExpiredNoTrace(Args &&... args)
     399             : {
     400        1476 :   moose::internal::mooseDeprecatedStream(
     401             :       Moose::out, true, true, false, std::forward<Args>(args)...);
     402        1473 : }
     403             : 
     404             : /// Emit an informational message with the given stringified, concatenated args.
     405             : template <typename... Args>
     406             : void
     407         224 : mooseInfo(Args &&... args)
     408             : {
     409         224 :   moose::internal::mooseInfoStream(Moose::out, std::forward<Args>(args)...);
     410         224 : }
     411             : 
     412             : /// Emit an informational message with the given stringified, concatenated args.
     413             : template <typename... Args>
     414             : void
     415        3861 : mooseInfoRepeated(Args &&... args)
     416             : {
     417        3861 :   moose::internal::mooseInfoStreamRepeated(Moose::out, std::forward<Args>(args)...);
     418        3861 : }

Generated by: LCOV version 1.14