LCOV - code coverage report
Current view: top level - src/base - MooseError.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fef103 Lines: 46 55 83.6 %
Date: 2025-09-03 20:01:23 Functions: 5 7 71.4 %
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             : #include "MooseError.h"
      11             : #include "MooseUtils.h"
      12             : #include "MooseVariable.h"
      13             : #include "Registry.h"
      14             : 
      15             : #include "libmesh/string_to_enum.h"
      16             : 
      17             : using namespace libMesh;
      18             : 
      19             : namespace moose
      20             : {
      21             : 
      22             : namespace internal
      23             : {
      24             : 
      25             : std::string
      26           4 : incompatVarMsg(MooseVariableFEBase & var1, MooseVariableFEBase & var2)
      27             : {
      28           4 :   std::stringstream ss;
      29           4 :   ss << libMesh::Utility::enum_to_string<FEFamily>(var1.feType().family) << ",ORDER"
      30           4 :      << var1.feType().order
      31           8 :      << " != " << libMesh::Utility::enum_to_string<FEFamily>(var2.feType().family) << ",ORDER"
      32           4 :      << var2.feType().order;
      33           8 :   return ss.str();
      34           4 : }
      35             : 
      36             : std::string
      37       44053 : mooseMsgFmt(const std::string & msg, const std::string & title, const std::string & color)
      38             : {
      39       44053 :   std::ostringstream oss;
      40       44053 :   oss << "\n" << color << "\n" << title << "\n" << msg << COLOR_DEFAULT << "\n";
      41       88106 :   return oss.str();
      42       44053 : }
      43             : 
      44             : std::string
      45           0 : mooseMsgFmt(const std::string & msg, const std::string & color)
      46             : {
      47           0 :   std::ostringstream oss;
      48           0 :   oss << "\n" << color << "\n" << msg << COLOR_DEFAULT << "\n";
      49           0 :   return oss.str();
      50           0 : }
      51             : 
      52             : [[noreturn]] void
      53        4560 : mooseErrorRaw(std::string msg,
      54             :               const std::string & prefix /* = "" */,
      55             :               const hit::Node * node /* = nullptr */)
      56             : {
      57        4560 :   if (Moose::_throw_on_error)
      58         243 :     throw MooseRuntimeError(msg, node);
      59             : 
      60             :   static std::atomic_flag aborting = ATOMIC_FLAG_INIT;
      61        4317 :   if (aborting.test_and_set(std::memory_order_acq_rel))
      62             :     // Another thread has gone before us. MPI_Abort, despite its name, does not behave like
      63             :     // std::abort but instead calls exit handlers and destroys statics. So we don't want to touch
      64             :     // anything static at this point. We'll just wait until the winning thread has incurred program
      65             :     // exit
      66             :     for (;;)
      67             :       // Don't burn cpu
      68          14 :       pause();
      69             :   else
      70             :   {
      71        4303 :     std::ostringstream oss;
      72        4303 :     if (!msg.empty())
      73             :     {
      74             :       // If we have a node available, add in the hit context (file location)
      75        4303 :       if (node)
      76        2925 :         msg = Moose::hitMessagePrefix(*node) + msg;
      77             : 
      78       12909 :       msg = mooseMsgFmt(msg, "*** ERROR ***", COLOR_RED);
      79             : 
      80        4303 :       oss << msg << "\n";
      81             : 
      82             :       // this independent flush of the partial error message (i.e. without the
      83             :       // trace) is here because trace retrieval can be slow in some
      84             :       // circumstances, and we want to get the error message out ASAP.
      85        4303 :       msg = oss.str();
      86        4303 :       if (!prefix.empty())
      87          40 :         MooseUtils::indentMessage(prefix, msg);
      88             :       {
      89        4303 :         Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
      90        4303 :         Moose::err << msg << std::flush;
      91        4303 :       }
      92             : 
      93        8606 :       oss.str("");
      94             :     }
      95             : 
      96        4303 :     if (Moose::show_trace && libMesh::global_n_processors() == 1)
      97        2710 :       print_trace(oss);
      98             : 
      99             :     {
     100        4303 :       Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     101        4303 :       Moose::err << msg << std::flush;
     102             : 
     103        4303 :       if (libMesh::global_n_processors() > 1)
     104           0 :         libMesh::write_traceout();
     105        4303 :     }
     106             : 
     107        4303 :     MOOSE_ABORT;
     108           0 :   }
     109             : }
     110             : 
     111             : void
     112       42852 : mooseStreamAll(std::ostringstream &)
     113             : {
     114       42852 : }
     115             : 
     116             : std::string
     117           6 : formatMooseDocumentedError(const std::string & repo_name,
     118             :                            const unsigned int issue_num,
     119             :                            const std::string & msg)
     120             : {
     121           6 :   const auto & repo_url = Registry::getRepositoryURL(repo_name);
     122           6 :   std::stringstream oss;
     123           6 :   oss << msg << "\n\nThis error is documented at " << repo_url << "/issues/" << issue_num << ".";
     124          12 :   return oss.str();
     125           6 : }
     126             : 
     127             : } // namespace internal
     128             : 
     129             : void
     130           0 : translateMetaPhysicLError(const MetaPhysicL::LogicError &)
     131             : {
     132           0 :   mooseError(
     133             :       "We caught a MetaPhysicL error in while performing element or face loops. This is "
     134             :       "potentially due to AD not having a sufficiently large derivative container size. To "
     135             :       "increase the AD container size, you can run configure in the MOOSE root directory with the "
     136             :       "'--with-derivative-size=<n>' option and then recompile. Other causes of MetaPhysicL logic "
     137             :       "errors include evaluating functions where they are not defined or differentiable like sqrt "
     138             :       "(which gets called for vector norm functions) or log with arguments <= 0");
     139             : }
     140             : 
     141             : } // namespace moose

Generated by: LCOV version 1.14