The Gaudi Framework  master (37c0b60a)
ExceptionSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // ============================================================================
12 // Include files
13 // ============================================================================
14 // STD & STL
15 // ============================================================================
16 #include <algorithm>
17 #include <cassert>
18 // ============================================================================
19 // GaudiKernel
20 // ============================================================================
22 // ============================================================================
23 // Local
24 // ============================================================================
25 #include "ExceptionSvc.h"
26 // ============================================================================
27 
28 #include <boost/regex.hpp>
29 
30 using namespace std;
31 
32 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
33 
35 
36 inline void toupper( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), (int ( * )( int ))toupper ); }
37 
38 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39 
42  if ( status.isFailure() ) { return status; }
43 
44  string key = m_mode_exc_s.value();
45 
46  auto loc = key.find( " " );
47  std::string mode = key.substr( 0, loc );
48 
49  toupper( mode );
50 
51  if ( mode == "NONE" ) {
52  m_mode_exc = NONE;
53  } else if ( mode == "ALL" ) {
54  m_mode_exc = ALL;
55  } else {
56  error() << "Unknown mode for Exception handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
57  << endmsg;
59  return StatusCode::FAILURE;
60  }
61 
62  if ( loc == string::npos ) {
63  key.clear();
64  } else {
65  key = key.substr( loc + 1 );
66  }
67 
68  std::string VAL, TAG;
69 
70  static const boost::regex exp{ "[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*([^[:space:]]+)" };
71  static const auto tok_end = boost::sregex_iterator();
72  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
73  TAG = ( *tok_iter )[1];
74  VAL = ( *tok_iter )[2];
75  toupper( VAL );
76 
77  if ( VAL == "SUCCESS" ) {
78  m_retCodesExc[TAG] = SUCCESS;
79  } else if ( VAL == "FAILURE" ) {
80  m_retCodesExc[TAG] = FAILURE;
81  } else if ( VAL == "REVOVERABLE" ) {
82  m_retCodesExc[TAG] = RECOVERABLE;
83  } else if ( VAL == "RETHROW" ) {
84  m_retCodesExc[TAG] = RETHROW;
85  } else if ( VAL == "DEFAULT" ) {
86  m_retCodesExc[TAG] = DEFAULT;
87  } else {
88  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
89  << " Must be one of: DEFAULT, SUCCESS, FAILURE, RECOVERABLE, RETHROW" << endmsg;
91  return StatusCode::FAILURE;
92  }
93 
94  if ( msgLevel( MSG::DEBUG ) )
95  debug() << "Will catch exceptions thrown by: " << TAG << " -> action: " << VAL << endmsg;
96  }
97 
98  // now process errors
99  key = m_mode_err_s.value();
100 
101  loc = key.find( " " );
102  mode = key.substr( 0, loc );
103 
104  toupper( mode );
105 
106  if ( mode == "NONE" ) {
107  m_mode_err = NONE;
108  } else if ( mode == "ALL" ) {
109  m_mode_err = ALL;
110  } else {
111  error() << "Unknown mode for Error handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
112  << endmsg;
114  return StatusCode::FAILURE;
115  }
116 
117  if ( loc == string::npos ) {
118  key.clear();
119  } else {
120  key = key.substr( loc + 1 );
121  }
122 
123  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
124  TAG = ( *tok_iter )[1];
125  VAL = ( *tok_iter )[2];
126  toupper( VAL );
127 
128  if ( VAL == "SUCCESS" ) {
129  m_retCodesErr[TAG] = SUCCESS;
130  } else if ( VAL == "FAILURE" ) {
131  m_retCodesErr[TAG] = FAILURE;
132  } else if ( VAL == "RECOVERABLE" ) {
133  m_retCodesErr[TAG] = RECOVERABLE;
134  } else {
135  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
136  << " Must be one of: SUCCESS, FAILURE, RECOVERABLE" << endmsg;
138  return StatusCode::FAILURE;
139  }
140 
141  if ( msgLevel( MSG::DEBUG ) )
142  debug() << "Will process Errors returned by: " << TAG << " -> action: " << VAL << endmsg;
143  }
144  return status;
145 }
146 
147 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
148 
150  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling Error from " << alg.name() << endmsg;
151 
152  // is this Alg special?
153  auto i = m_retCodesErr.find( alg.name() );
154  if ( i != m_retCodesErr.end() ) {
155  switch ( i->second ) {
156  case SUCCESS:
157  return StatusCode::SUCCESS;
158  case FAILURE:
159  return StatusCode::FAILURE;
160  case RECOVERABLE:
162  // should never get here
163  case RETHROW:
164  break;
165  case DEFAULT:
166  break;
167  }
168 
169  } else {
170 
171  if ( m_mode_err == ALL ) return StatusCode::FAILURE; // turn it into FAILURE
172  assert( m_mode_err == NONE );
173  // don't touch the return code
174  return st;
175  }
176  return StatusCode::FAILURE;
177 }
178 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
179 
181 
182  // is this Alg special?
183  auto i = m_retCodesExc.find( alg.name() );
184  if ( i != m_retCodesExc.end() ) {
185 
186  switch ( i->second ) {
187  case DEFAULT:
188  return StatusCode::FAILURE; // there is no default
189  case SUCCESS:
190  return StatusCode::SUCCESS;
191  case FAILURE:
192  return StatusCode::FAILURE;
193  case RECOVERABLE:
195  case RETHROW:
196  throw; // cppcheck-suppress rethrowNoCurrentException
197  }
198  }
199 
200  if ( m_mode_exc == ALL ) { throw; } // cppcheck-suppress rethrowNoCurrentException
201  assert( m_mode_exc == NONE );
202  return StatusCode::FAILURE;
203 }
204 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
205 
207  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling unknown exception for " << alg.name() << endmsg;
208  return process( alg );
209 }
210 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
211 
213  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling std:except: \"" << exc.what() << "\" for " << alg.name() << endmsg;
214  return process( alg );
215 }
216 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
217 
219  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling GaudiException: \"" << exc << "\" for " << alg.name() << endmsg;
220  return process( alg );
221 }
222 
223 // ============================================================================
224 // The END
225 // ============================================================================
GaudiPython.Bindings.FAILURE
FAILURE
Definition: Bindings.py:84
ExceptionSvc::process
virtual StatusCode process(const INamedInterface &o) const
Definition: ExceptionSvc.cpp:180
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
std::string
STL class.
gaudirun.process
process
Definition: gaudirun.py:548
std::exception
STL class.
gaudirun.s
string s
Definition: gaudirun.py:346
GaudiException
Definition: GaudiException.h:31
GaudiKernel.Constants.ALL
ALL
Definition: Constants.py:28
ExceptionSvc::initialize
StatusCode initialize() override
initialize the service
Definition: ExceptionSvc.cpp:40
ExceptionSvc::handleErr
StatusCode handleErr(const INamedInterface &o, const StatusCode &s) const override
Handle errors.
Definition: ExceptionSvc.cpp:149
ManySmallAlgs.alg
alg
Definition: ManySmallAlgs.py:81
StatusCode
Definition: StatusCode.h:65
ExceptionSvc::handle
StatusCode handle(const INamedInterface &o, const GaudiException &e) const override
Handle caught GaudiExceptions.
Definition: ExceptionSvc.cpp:218
Gaudi::StateMachine::OFFLINE
@ OFFLINE
Definition: StateMachine.h:23
GaudiPython.Bindings.SUCCESS
SUCCESS
Definition: Bindings.py:83
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
std::transform
T transform(T... args)
std::toupper
T toupper(T... args)
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ExceptionSvc.h
INamedInterface
Definition: INamedInterface.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
std::endl
T endl(T... args)
std::exp
T exp(T... args)
std::string::begin
T begin(T... args)
std
STL namespace.
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
std::string::end
T end(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
ISvcLocator.h
StatusCode::RECOVERABLE
constexpr static const auto RECOVERABLE
Definition: StatusCode.h:102
ProduceConsume.key
key
Definition: ProduceConsume.py:84
std::exception::what
T what(T... args)
ExceptionSvc
Definition: ExceptionSvc.h:29