LCOV - code coverage report
Current view: top level - include/base - MooseError.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 82 83 98.8 %
Date: 2025-07-17 01:28:37 Functions: 1686 3781 44.6 %
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             : // this function allows streaming tuples to ostreams
      33             : template <size_t n, typename... T>
      34             : void
      35             : print_tuple(std::ostream & os, const std::tuple<T...> & tup)
      36             : {
      37             :   if constexpr (n < sizeof...(T))
      38             :   {
      39             :     if (n != 0)
      40             :       os << ", ";
      41             :     os << std::get<n>(tup);
      42             :     print_tuple<n + 1>(os, tup);
      43             :   }
      44             : }
      45             : template <typename... T>
      46             : std::ostream &
      47             : operator<<(std::ostream & os, const std::tuple<T...> & tup)
      48             : {
      49             :   os << "[";
      50             :   print_tuple<0>(os, tup);
      51             :   return os << "]";
      52             : }
      53             : 
      54             : /// Application abort macro. Uses MPI_Abort if available, std::abort otherwise
      55             : #if defined(LIBMESH_HAVE_MPI)
      56             : #define MOOSE_ABORT                                                                                \
      57             :   do                                                                                               \
      58             :   {                                                                                                \
      59             :     MPI_Abort(libMesh::GLOBAL_COMM_WORLD, 1);                                                      \
      60             :     std::abort();                                                                                  \
      61             :   } while (0)
      62             : #else
      63             : #define MOOSE_ABORT                                                                                \
      64             :   do                                                                                               \
      65             :   {                                                                                                \
      66             :     std::abort();                                                                                  \
      67             :   } while (0)
      68             : #endif
      69             : 
      70             : #define mooseDoOnce(do_this)                                                                       \
      71             :   do                                                                                               \
      72             :   {                                                                                                \
      73             :     static bool did_this_already = false;                                                          \
      74             :     if (Moose::show_multiple || !did_this_already)                                                 \
      75             :     {                                                                                              \
      76             :       did_this_already = true;                                                                     \
      77             :       do_this;                                                                                     \
      78             :     }                                                                                              \
      79             :   } while (0)
      80             : 
      81             : #define mooseCheckMPIErr(err)                                                                      \
      82             :   do                                                                                               \
      83             :   {                                                                                                \
      84             :     if (err != MPI_SUCCESS)                                                                        \
      85             :     {                                                                                              \
      86             :       if (libMesh::global_n_processors() == 1)                                                     \
      87             :         libMesh::print_trace();                                                                    \
      88             :       libmesh_here();                                                                              \
      89             :       MOOSE_ABORT;                                                                                 \
      90             :     }                                                                                              \
      91             :   } while (0)
      92             : 
      93             : #define mooseException(...)                                                                        \
      94             :   do                                                                                               \
      95             :   {                                                                                                \
      96             :     throw MooseException(__VA_ARGS__);                                                             \
      97             :   } while (0)
      98             : 
      99             : #ifdef NDEBUG
     100             : #define mooseAssert(asserted, msg) ((void)0)
     101             : #else
     102             : #define mooseAssert(asserted, msg)                                                                 \
     103             :   do                                                                                               \
     104             :   {                                                                                                \
     105             :     if (!(asserted))                                                                               \
     106             :     {                                                                                              \
     107             :       std::ostringstream _assert_oss_;                                                             \
     108             :       _assert_oss_ << COLOR_RED << "\n\nAssertion `" #asserted "' failed\n"                        \
     109             :                    << msg << "\nat " << __FILE__ << ", line " << __LINE__ << COLOR_DEFAULT         \
     110             :                    << std::endl;                                                                   \
     111             :       if (Moose::_throw_on_error)                                                                  \
     112             :         throw std::runtime_error(_assert_oss_.str());                                              \
     113             :       else                                                                                         \
     114             :       {                                                                                            \
     115             :         Moose::err << _assert_oss_.str() << std::flush;                                            \
     116             :         if (libMesh::global_n_processors() == 1)                                                   \
     117             :           libMesh::print_trace();                                                                  \
     118             :         else                                                                                       \
     119             :           libMesh::write_traceout();                                                               \
     120             :         libmesh_here();                                                                            \
     121             :         MOOSE_ABORT;                                                                               \
     122             :       }                                                                                            \
     123             :     }                                                                                              \
     124             :   } while (0)
     125             : #endif
     126             : 
     127             : template <typename... Args>
     128             : [[noreturn]] void mooseError(Args &&... args);
     129             : 
     130             : class MooseVariableFieldBase;
     131             : 
     132             : namespace moose
     133             : {
     134             : 
     135             : namespace internal
     136             : {
     137             : inline libMesh::Threads::spin_mutex moose_stream_lock;
     138             : 
     139             : /// Builds and returns a string of the form:
     140             : ///
     141             : ///     [var1-elemtype],ORDER[var1-order] != [var2-elemtype],ORDER[var2-order]
     142             : ///
     143             : /// This is a convenience function to be used when error messages (especially with paramError)
     144             : /// need to report that variable types are incompatible (e.g. with residual save-in).
     145             : std::string incompatVarMsg(MooseVariableFieldBase & var1, MooseVariableFieldBase & var2);
     146             : 
     147             : /**
     148             :  * Format a message for output with a title
     149             :  * @param msg The message to print
     150             :  * @param title The title that will go on a line before the message
     151             :  * @param color The color to print the message in
     152             :  * @return The formatted message
     153             :  */
     154             : std::string
     155             : mooseMsgFmt(const std::string & msg, const std::string & title, const std::string & color);
     156             : 
     157             : /**
     158             :  * Format a message for output without a title
     159             :  * @param msg The message to print
     160             :  * @param color The color to print the message in
     161             :  * @return The formatted message
     162             :  */
     163             : std::string mooseMsgFmt(const std::string & msg, const std::string & color);
     164             : 
     165             : [[noreturn]] void mooseErrorRaw(std::string msg, const std::string prefix = "");
     166             : 
     167             : /**
     168             :  * All of the following are not meant to be called directly - they are called by the normal macros
     169             :  * (mooseError(), etc.) down below
     170             :  * @{
     171             :  */
     172             : void mooseStreamAll(std::ostringstream & ss);
     173             : 
     174             : template <typename T, typename... Args>
     175             : void
     176       66387 : mooseStreamAll(std::ostringstream & ss, T && val, Args &&... args)
     177             : {
     178       66387 :   ss << val;
     179       66387 :   mooseStreamAll(ss, std::forward<Args>(args)...);
     180       66387 : }
     181             : 
     182             : template <typename S, typename... Args>
     183             : void
     184        3520 : mooseWarningStream(S & oss, Args &&... args)
     185             : {
     186        3520 :   if (Moose::_warnings_are_errors)
     187         194 :     mooseError(std::forward<Args>(args)...);
     188             : 
     189        3326 :   std::ostringstream ss;
     190        3326 :   mooseStreamAll(ss, args...);
     191        3326 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     192        3326 :   if (Moose::_throw_on_warning)
     193           4 :     throw std::runtime_error(msg);
     194             : 
     195             :   {
     196        3322 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     197        3322 :     oss << msg << std::flush;
     198        3322 :   }
     199        3330 : }
     200             : 
     201             : template <typename S, typename... Args>
     202             : void
     203          49 : mooseUnusedStream(S & oss, Args &&... args)
     204             : {
     205          49 :   std::ostringstream ss;
     206          49 :   mooseStreamAll(ss, args...);
     207          49 :   std::string msg = mooseMsgFmt(ss.str(), "*** Warning ***", COLOR_YELLOW);
     208          49 :   if (Moose::_throw_on_warning)
     209           0 :     throw std::runtime_error(msg);
     210             : 
     211             :   {
     212          49 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     213          49 :     oss << msg << std::flush;
     214          49 :   }
     215          49 : }
     216             : 
     217             : template <typename S, typename... Args>
     218             : void
     219       15817 : mooseInfoStreamRepeated(S & oss, Args &&... args)
     220             : {
     221       15817 :   std::ostringstream ss;
     222       15817 :   mooseStreamAll(ss, args...);
     223       15817 :   std::string msg = mooseMsgFmt(ss.str(), "*** Info ***", COLOR_CYAN);
     224             :   {
     225       15817 :     libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     226       15817 :     oss << msg << std::flush;
     227       15817 :   }
     228       15817 : }
     229             : 
     230             : template <typename S, typename... Args>
     231             : void
     232        7099 : mooseInfoStream(S & oss, Args &&... args)
     233             : {
     234        7099 :   mooseDoOnce(mooseInfoStreamRepeated(oss, args...););
     235        7099 : }
     236             : 
     237             : template <typename S, typename... Args>
     238             : void
     239       14061 : mooseDeprecatedStream(S & oss, const bool expired, const bool print_title, Args &&... args)
     240             : {
     241       14061 :   if (Moose::_deprecated_is_error)
     242          13 :     mooseError("\n\nDeprecated code:\n", std::forward<Args>(args)...);
     243             : 
     244       14048 :   std::ostringstream ss;
     245       14048 :   mooseStreamAll(ss, args...);
     246             : 
     247       14048 :   const auto color = expired ? COLOR_RED : COLOR_YELLOW;
     248       14048 :   std::string msg =
     249             :       print_title
     250       14048 :           ? mooseMsgFmt(
     251             :                 ss.str(),
     252             :                 "*** Warning, This code is deprecated and will be removed in future versions:",
     253             :                 color)
     254             :           : mooseMsgFmt(ss.str(), color);
     255       14048 :   oss << msg;
     256       14048 :   ss.str("");
     257       14048 :   if (Moose::show_trace)
     258             :   {
     259       11469 :     if (libMesh::global_n_processors() == 1)
     260        6391 :       libMesh::print_trace(ss);
     261             :     else
     262        5078 :       libMesh::write_traceout();
     263             :     {
     264       11469 :       libMesh::Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     265       11469 :       oss << ss.str() << std::endl;
     266       11469 :     };
     267             :   };
     268       14048 : }
     269             : /**
     270             :  * @}
     271             :  */
     272             : 
     273             : /**
     274             :  * Formats a documented error. A documented error is an error that has
     275             :  * an issue associated with it.
     276             :  *
     277             :  * The repository name \p repo_name links a named repository to a URL
     278             :  * and should be registered at the application level with registerRepository().
     279             :  * See Moose.C for an example of the "moose" repository registration.
     280             :  *
     281             :  * @param repo_name The repository name where the issue resides
     282             :  * @param issue_num The number of the issue
     283             :  * @param msg The specific error message
     284             :  */
     285             : std::string formatMooseDocumentedError(const std::string & repo_name,
     286             :                                        const unsigned int issue_num,
     287             :                                        const std::string & msg);
     288             : } // namespace internal
     289             : 
     290             : /**
     291             :  * emit a relatively clear error message when we catch a MetaPhysicL logic error
     292             :  */
     293             : void translateMetaPhysicLError(const MetaPhysicL::LogicError &);
     294             : 
     295             : } // namespace moose
     296             : 
     297             : /// Emit an error message with the given stringified, concatenated args and
     298             : /// terminate the application.  Inside static functions, you will need to
     299             : /// explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     300             : template <typename... Args>
     301             : [[noreturn]] void
     302        1406 : mooseError(Args &&... args)
     303             : {
     304        1406 :   std::ostringstream oss;
     305        1406 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     306        2048 :   moose::internal::mooseErrorRaw(oss.str());
     307         214 : }
     308             : 
     309             : /**
     310             :  * Emit a documented error message with the given stringified, concatenated args
     311             :  * and terminate the application.  Inside static functions, you will need to
     312             :  * explicitly scope your mooseError call - i.e. do "::mooseError(arg1, ...);".
     313             :  *
     314             :  * Here, a documented error message is one with an associated issue. See
     315             :  * formatMooseDocumentedError for more information.
     316             :  *
     317             :  * @param repo_name The repository name where the issue resides
     318             :  * @param issue_num The number of the issue
     319             :  * @param args The error message to stringify
     320             :  **/
     321             : template <typename... Args>
     322             : [[noreturn]] void
     323           1 : mooseDocumentedError(const std::string & repo_name, const unsigned int issue_num, Args &&... args)
     324             : {
     325           1 :   std::ostringstream oss;
     326           1 :   moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
     327           5 :   moose::internal::mooseErrorRaw(
     328             :       moose::internal::formatMooseDocumentedError(repo_name, issue_num, oss.str()));
     329           1 : }
     330             : 
     331             : /// Emit a warning message with the given stringified, concatenated args.
     332             : /// Inside static functions, you will need to explicitly scope your
     333             : /// mooseWarning call - i.e. do "::mooseWarning(arg1, ...);".
     334             : template <typename... Args>
     335             : void
     336        1138 : mooseWarning(Args &&... args)
     337             : {
     338        1138 :   moose::internal::mooseWarningStream(Moose::out, std::forward<Args>(args)...);
     339        1099 : }
     340             : 
     341             : /// Warning message used to notify the users of unused parts of their input files
     342             : /// Really used internally by the parser and shouldn't really be called elsewhere
     343             : template <typename... Args>
     344             : void
     345          49 : mooseUnused(Args &&... args)
     346             : {
     347          49 :   moose::internal::mooseUnusedStream(Moose::out, std::forward<Args>(args)...);
     348          49 : }
     349             : 
     350             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     351             : template <typename... Args>
     352             : void
     353       10475 : mooseDeprecated(Args &&... args)
     354             : {
     355       10475 :   moose::internal::mooseDeprecatedStream(Moose::out, false, true, std::forward<Args>(args)...);
     356       10474 : }
     357             : 
     358             : /// Emit a deprecated code/feature message with the given stringified, concatenated args.
     359             : template <typename... Args>
     360             : void
     361        1018 : mooseDeprecationExpired(Args &&... args)
     362             : {
     363        1018 :   moose::internal::mooseDeprecatedStream(Moose::out, true, true, std::forward<Args>(args)...);
     364        1014 : }
     365             : 
     366             : /// Emit an informational message with the given stringified, concatenated args.
     367             : template <typename... Args>
     368             : void
     369         703 : mooseInfo(Args &&... args)
     370             : {
     371         703 :   moose::internal::mooseInfoStream(Moose::out, std::forward<Args>(args)...);
     372         703 : }
     373             : 
     374             : /// Emit an informational message with the given stringified, concatenated args.
     375             : template <typename... Args>
     376             : void
     377       11104 : mooseInfoRepeated(Args &&... args)
     378             : {
     379       11104 :   moose::internal::mooseInfoStreamRepeated(Moose::out, std::forward<Args>(args)...);
     380       11104 : }

Generated by: LCOV version 1.14