Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ExceptionSvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD & STL
5 // ============================================================================
6 #include <algorithm>
7 #include <cassert>
8 // ============================================================================
9 // GaudiKernel
10 // ============================================================================
12 // ============================================================================
13 // Local
14 // ============================================================================
15 #include "ExceptionSvc.h"
16 // ============================================================================
17 
18 #include <boost/regex.hpp>
19 
20 using namespace std;
21 
22 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 
25 
26 inline void toupper( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), (int ( * )( int ))toupper ); }
27 
28 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
29 
32  if ( status.isFailure() ) { return status; }
33 
34  string key = m_mode_exc_s.value();
35 
36  auto loc = key.find( " " );
37  std::string mode = key.substr( 0, loc );
38 
39  toupper( mode );
40 
41  if ( mode == "NONE" ) {
42  m_mode_exc = NONE;
43  } else if ( mode == "ALL" ) {
44  m_mode_exc = ALL;
45  } else {
46  error() << "Unknown mode for Exception handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
47  << endmsg;
49  return StatusCode::FAILURE;
50  }
51 
52  if ( loc == string::npos ) {
53  key.clear();
54  } else {
55  key = key.substr( loc + 1 );
56  }
57 
58  std::string VAL, TAG;
59 
60  static const boost::regex exp{"[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*([^[:space:]]+)"};
61  static const auto tok_end = boost::sregex_iterator();
62  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
63  TAG = ( *tok_iter )[1];
64  VAL = ( *tok_iter )[2];
65  toupper( VAL );
66 
67  if ( VAL == "SUCCESS" ) {
68  m_retCodesExc[TAG] = SUCCESS;
69  } else if ( VAL == "FAILURE" ) {
70  m_retCodesExc[TAG] = FAILURE;
71  } else if ( VAL == "REVOVERABLE" ) {
72  m_retCodesExc[TAG] = RECOVERABLE;
73  } else if ( VAL == "RETHROW" ) {
74  m_retCodesExc[TAG] = RETHROW;
75  } else if ( VAL == "DEFAULT" ) {
76  m_retCodesExc[TAG] = DEFAULT;
77  } else {
78  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
79  << " Must be one of: DEFAULT, SUCCESS, FAILURE, RECOVERABLE, RETHROW" << endmsg;
81  return StatusCode::FAILURE;
82  }
83 
84  if ( msgLevel( MSG::DEBUG ) )
85  debug() << "Will catch exceptions thrown by: " << TAG << " -> action: " << VAL << endmsg;
86  }
87 
88  // now process errors
89  key = m_mode_err_s.value();
90 
91  loc = key.find( " " );
92  mode = key.substr( 0, loc );
93 
94  toupper( mode );
95 
96  if ( mode == "NONE" ) {
97  m_mode_err = NONE;
98  } else if ( mode == "ALL" ) {
99  m_mode_err = ALL;
100  } else {
101  error() << "Unknown mode for Error handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
102  << endmsg;
104  return StatusCode::FAILURE;
105  }
106 
107  if ( loc == string::npos ) {
108  key.clear();
109  } else {
110  key = key.substr( loc + 1 );
111  }
112 
113  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
114  TAG = ( *tok_iter )[1];
115  VAL = ( *tok_iter )[2];
116  toupper( VAL );
117 
118  if ( VAL == "SUCCESS" ) {
119  m_retCodesErr[TAG] = SUCCESS;
120  } else if ( VAL == "FAILURE" ) {
121  m_retCodesErr[TAG] = FAILURE;
122  } else if ( VAL == "RECOVERABLE" ) {
123  m_retCodesErr[TAG] = RECOVERABLE;
124  } else {
125  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
126  << " Must be one of: SUCCESS, FAILURE, RECOVERABLE" << endmsg;
128  return StatusCode::FAILURE;
129  }
130 
131  if ( msgLevel( MSG::DEBUG ) )
132  debug() << "Will process Errors returned by: " << TAG << " -> action: " << VAL << endmsg;
133  }
134  return status;
135 }
136 
137 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
138 
140  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling Error from " << alg.name() << endmsg;
141 
142  // is this Alg special?
143  auto i = m_retCodesErr.find( alg.name() );
144  if ( i != m_retCodesErr.end() ) {
145  switch ( i->second ) {
146  case SUCCESS:
147  return StatusCode::SUCCESS;
148  case FAILURE:
149  return StatusCode::FAILURE;
150  case RECOVERABLE:
152  // should never get here
153  case RETHROW:
154  break;
155  case DEFAULT:
156  break;
157  }
158 
159  } else {
160 
161  if ( m_mode_err == ALL ) return StatusCode::FAILURE; // turn it into FAILURE
162  assert( m_mode_err == NONE );
163  // don't touch the return code
164  return st;
165  }
166  return StatusCode::FAILURE;
167 }
168 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
169 
171 
172  // is this Alg special?
173  auto i = m_retCodesExc.find( alg.name() );
174  if ( i != m_retCodesExc.end() ) {
175 
176  switch ( i->second ) {
177  case DEFAULT:
178  return StatusCode::FAILURE; // there is no default
179  case SUCCESS:
180  return StatusCode::SUCCESS;
181  case FAILURE:
182  return StatusCode::FAILURE;
183  case RECOVERABLE:
185  case RETHROW:
186  throw;
187  }
188  }
189 
190  if ( m_mode_exc == ALL ) { throw; }
191  assert( m_mode_exc == NONE );
192  return StatusCode::FAILURE;
193 }
194 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
195 
197  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling unknown exception for " << alg.name() << endmsg;
198  return process( alg );
199 }
200 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
201 
203  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling std:except: \"" << exc.what() << "\" for " << alg.name() << endmsg;
204  return process( alg );
205 }
206 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
207 
209  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling GaudiException: \"" << exc << "\" for " << alg.name() << endmsg;
210  return process( alg );
211 }
212 
213 // ============================================================================
214 // The END
215 // ============================================================================
StatusCode initialize() override
Definition: Service.cpp:60
Define general base for Gaudi exception.
T exp(T...args)
constexpr static const auto RECOVERABLE
Definition: StatusCode.h:87
T endl(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
T end(T...args)
bool isFailure() const
Definition: StatusCode.h:130
STL class.
#define DECLARE_COMPONENT(type)
T toupper(T...args)
T what(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Simple implementation of IExceptionSvc abstract interface.
Definition: ExceptionSvc.h:19
StatusCode initialize() override
initialize the service
T clear(T...args)
STL class.
StatusCode handle(const INamedInterface &o, const GaudiException &e) const override
Handle caught GaudiExceptions.
IInterface compliant class extending IInterface with the name() method.
T find(T...args)
T begin(T...args)
StatusCode handleErr(const INamedInterface &o, const StatusCode &s) const override
Handle errors.
string s
Definition: gaudirun.py:312
constexpr static const auto FAILURE
Definition: StatusCode.h:86
T substr(T...args)
T transform(T...args)
virtual StatusCode process(const INamedInterface &o) const
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
virtual const std::string & name() const =0
Retrieve the name of the instance.