LCOV - code coverage report
Current view: top level - src/base - MooseError.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 99787a Lines: 47 55 85.5 %
Date: 2025-10-14 20:01:24 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       48566 : mooseMsgFmt(const std::string & msg, const std::string & title, const std::string & color)
      38             : {
      39       48566 :   std::ostringstream oss;
      40       48566 :   oss << "\n" << color << "\n" << title << "\n" << msg << COLOR_DEFAULT << "\n";
      41       97132 :   return oss.str();
      42       48566 : }
      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        4863 : mooseErrorRaw(std::string msg,
      54             :               const std::string & prefix /* = "" */,
      55             :               const hit::Node * node /* = nullptr */)
      56             : {
      57        4863 :   if (Moose::_throw_on_error)
      58         500 :     throw MooseRuntimeError(msg, node);
      59             : 
      60             :   // Atomic that will be set as soon as any thread hits this method
      61             :   static std::atomic_flag aborting = ATOMIC_FLAG_INIT;
      62             : 
      63             :   // This branch will be hit after another thread has already set the atomic.
      64             :   // MPI_Abort, despite its name, does not behave like std::abort but instead
      65             :   // calls exit handlers and destroys statics. So we don't want to touch
      66             :   // anything static at this point. We'll just wait until the winning thread
      67             :   // has incurred program exit
      68        4363 :   if (aborting.test_and_set(std::memory_order_acq_rel))
      69             :   {
      70             :     // Waiting for the other thread(s), not burning CPU
      71             :     for (;;)
      72          14 :       pause();
      73             :   }
      74             :   // We're the first thread to hit this method (we set the atomic), so we're
      75             :   // responsible for dumping the error and trace(s) while the remaining
      76             :   // threads wait for us to exit (via MOOSE_ABORT)
      77             :   else
      78             :   {
      79             :     // Output the message if there is one, but flush it without the trace
      80             :     // as trace retrieval can be slow in some circumstances and we want to
      81             :     // get the error message out ASAP
      82        4349 :     if (!msg.empty())
      83             :     {
      84             :       // If we have a node available, add in the hit context (file location)
      85        4349 :       if (node)
      86        2929 :         msg = Moose::hitMessagePrefix(*node) + msg;
      87             : 
      88       13047 :       msg = mooseMsgFmt(msg, "*** ERROR ***", COLOR_RED) + "\n";
      89        4349 :       if (!prefix.empty()) // multiapp prefix
      90          40 :         MooseUtils::indentMessage(prefix, msg);
      91             : 
      92             :       {
      93        4349 :         Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
      94        4349 :         Moose::err << msg << std::flush;
      95        4349 :       }
      96             :     }
      97             : 
      98             :     // Print the trace if enabled and on a single rank
      99        4349 :     if (Moose::show_trace && libMesh::global_n_processors() == 1)
     100             :     {
     101        2760 :       std::ostringstream oss;
     102        2760 :       print_trace(oss);
     103        2760 :       auto trace = oss.str();
     104        2760 :       if (!prefix.empty()) // multiapp prefix
     105          32 :         MooseUtils::indentMessage(prefix, trace);
     106             : 
     107             :       {
     108        2760 :         Threads::spin_mutex::scoped_lock lock(moose_stream_lock);
     109        2760 :         Moose::err << trace << std::flush;
     110        2760 :       }
     111        2760 :     }
     112             : 
     113             :     // In parallel with libMesh configured with --enable-tracefiles, this will
     114             :     // dump a trace for each rank to file
     115        4349 :     if (libMesh::global_n_processors() > 1)
     116           0 :       libMesh::write_traceout();
     117             : 
     118        4349 :     MOOSE_ABORT;
     119             :   }
     120             : }
     121             : 
     122             : void
     123       47582 : mooseStreamAll(std::ostringstream &)
     124             : {
     125       47582 : }
     126             : 
     127             : std::string
     128           8 : formatMooseDocumentedError(const std::string & repo_name,
     129             :                            const unsigned int issue_num,
     130             :                            const std::string & msg)
     131             : {
     132           8 :   const auto & repo_url = Registry::getRepositoryURL(repo_name);
     133           8 :   std::stringstream oss;
     134           8 :   oss << msg << "\n\nThis error is documented at " << repo_url << "/issues/" << issue_num << ".";
     135          16 :   return oss.str();
     136           8 : }
     137             : 
     138             : } // namespace internal
     139             : 
     140             : void
     141           0 : translateMetaPhysicLError(const MetaPhysicL::LogicError &)
     142             : {
     143           0 :   mooseError(
     144             :       "We caught a MetaPhysicL error in while performing element or face loops. This is "
     145             :       "potentially due to AD not having a sufficiently large derivative container size. To "
     146             :       "increase the AD container size, you can run configure in the MOOSE root directory with the "
     147             :       "'--with-derivative-size=<n>' option and then recompile. Other causes of MetaPhysicL logic "
     148             :       "errors include evaluating functions where they are not defined or differentiable like sqrt "
     149             :       "(which gets called for vector norm functions) or log with arguments <= 0");
     150             : }
     151             : 
     152             : } // namespace moose

Generated by: LCOV version 1.14