The Gaudi Framework  v30r3 (a5ef0a68)
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 
31 {
33  if ( status.isFailure() ) {
34  return status;
35  }
36 
37  string key = m_mode_exc_s.value();
38 
39  auto loc = key.find( " " );
40  std::string mode = key.substr( 0, loc );
41 
42  toupper( mode );
43 
44  if ( mode == "NONE" ) {
45  m_mode_exc = NONE;
46  } else if ( mode == "ALL" ) {
47  m_mode_exc = ALL;
48  } else {
49  error() << "Unknown mode for Exception handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
50  << endmsg;
52  return StatusCode::FAILURE;
53  }
54 
55  if ( loc == string::npos ) {
56  key.clear();
57  } else {
58  key = key.substr( loc + 1 );
59  }
60 
61  std::string VAL, TAG;
62 
63  static const boost::regex exp{"[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*([^[:space:]]+)"};
64  static const auto tok_end = boost::sregex_iterator();
65  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
66  TAG = ( *tok_iter )[1];
67  VAL = ( *tok_iter )[2];
68  toupper( VAL );
69 
70  if ( VAL == "SUCCESS" ) {
71  m_retCodesExc[TAG] = SUCCESS;
72  } else if ( VAL == "FAILURE" ) {
73  m_retCodesExc[TAG] = FAILURE;
74  } else if ( VAL == "REVOVERABLE" ) {
75  m_retCodesExc[TAG] = RECOVERABLE;
76  } else if ( VAL == "RETHROW" ) {
77  m_retCodesExc[TAG] = RETHROW;
78  } else if ( VAL == "DEFAULT" ) {
79  m_retCodesExc[TAG] = DEFAULT;
80  } else {
81  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
82  << " Must be one of: DEFAULT, SUCCESS, FAILURE, RECOVERABLE, RETHROW" << endmsg;
84  return StatusCode::FAILURE;
85  }
86 
87  if ( msgLevel( MSG::DEBUG ) )
88  debug() << "Will catch exceptions thrown by: " << TAG << " -> action: " << VAL << endmsg;
89  }
90 
91  // now process errors
92  key = m_mode_err_s.value();
93 
94  loc = key.find( " " );
95  mode = key.substr( 0, loc );
96 
97  toupper( mode );
98 
99  if ( mode == "NONE" ) {
100  m_mode_err = NONE;
101  } else if ( mode == "ALL" ) {
102  m_mode_err = ALL;
103  } else {
104  error() << "Unknown mode for Error handling: \"" << mode << "\". Default must be one of \"ALL\" or \"NONE\""
105  << endmsg;
107  return StatusCode::FAILURE;
108  }
109 
110  if ( loc == string::npos ) {
111  key.clear();
112  } else {
113  key = key.substr( loc + 1 );
114  }
115 
116  for ( auto tok_iter = boost::sregex_iterator( begin( key ), end( key ), exp ); tok_iter != tok_end; ++tok_iter ) {
117  TAG = ( *tok_iter )[1];
118  VAL = ( *tok_iter )[2];
119  toupper( VAL );
120 
121  if ( VAL == "SUCCESS" ) {
122  m_retCodesErr[TAG] = SUCCESS;
123  } else if ( VAL == "FAILURE" ) {
124  m_retCodesErr[TAG] = FAILURE;
125  } else if ( VAL == "RECOVERABLE" ) {
126  m_retCodesErr[TAG] = RECOVERABLE;
127  } else {
128  error() << "In JobOpts: unknown return code \"" << VAL << "\" for Algorithm " << TAG << std::endl
129  << " Must be one of: SUCCESS, FAILURE, RECOVERABLE" << endmsg;
131  return StatusCode::FAILURE;
132  }
133 
134  if ( msgLevel( MSG::DEBUG ) )
135  debug() << "Will process Errors returned by: " << TAG << " -> action: " << VAL << endmsg;
136  }
137  return status;
138 }
139 
140 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
141 
143 {
144  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling Error from " << alg.name() << endmsg;
145 
146  // is this Alg special?
147  auto i = m_retCodesErr.find( alg.name() );
148  if ( i != m_retCodesErr.end() ) {
149  switch ( i->second ) {
150  case SUCCESS:
151  return StatusCode::SUCCESS;
152  case FAILURE:
153  return StatusCode::FAILURE;
154  case RECOVERABLE:
156  // should never get here
157  case RETHROW:
158  break;
159  case DEFAULT:
160  break;
161  }
162 
163  } else {
164 
165  if ( m_mode_err == ALL ) return StatusCode::FAILURE; // turn it into FAILURE
166  assert( m_mode_err == NONE );
167  // don't touch the return code
168  return st;
169  }
170  return StatusCode::FAILURE;
171 }
172 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
173 
175 {
176 
177  // is this Alg special?
178  auto i = m_retCodesExc.find( alg.name() );
179  if ( i != m_retCodesExc.end() ) {
180 
181  switch ( i->second ) {
182  case DEFAULT:
183  return StatusCode::FAILURE; // there is no default
184  case SUCCESS:
185  return StatusCode::SUCCESS;
186  case FAILURE:
187  return StatusCode::FAILURE;
188  case RECOVERABLE:
190  case RETHROW:
191  throw;
192  }
193  }
194 
195  if ( m_mode_exc == ALL ) {
196  throw;
197  }
198  assert( m_mode_exc == NONE );
199  return StatusCode::FAILURE;
200 }
201 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
202 
204 {
205  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling unknown exception for " << alg.name() << endmsg;
206  return process( alg );
207 }
208 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
209 
211 {
212  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling std:except: \"" << exc.what() << "\" for " << alg.name() << endmsg;
213  return process( alg );
214 }
215 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
216 
218 {
219  if ( msgLevel( MSG::DEBUG ) ) debug() << "Handling GaudiException: \"" << exc << "\" for " << alg.name() << endmsg;
220  return process( alg );
221 }
222 
223 // ============================================================================
224 // The END
225 // ============================================================================
constexpr static const auto FAILURE
Definition: StatusCode.h:88
StatusCode initialize() override
Definition: Service.cpp:63
Define general base for Gaudi exception.
T exp(T...args)
T endl(T...args)
STL namespace.
T end(T...args)
bool isFailure() const
Definition: StatusCode.h:139
STL class.
#define DECLARE_COMPONENT(type)
T toupper(T...args)
T what(T...args)
constexpr static const auto RECOVERABLE
Definition: StatusCode.h:89
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
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.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
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:253
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:209
virtual const std::string & name() const =0
Retrieve the name of the instance.