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 <cassert>
7 #include <algorithm>
8 // ============================================================================
9 // GaudiKernel
10 // ============================================================================
11 #include "GaudiKernel/ISvcLocator.h"
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)
27 {
28  std::transform(s.begin(), s.end(), s.begin(),
29  (int(*)(int)) toupper);
30 }
31 
32 //
34 //
35 
36 ExceptionSvc::ExceptionSvc( const std::string& nam, ISvcLocator* svc )
37  : base_class( nam, svc )
38  , m_log(msgSvc(), name() )
39 {
40  // for exceptions
41  declareProperty( "Catch" , m_mode_exc_s="ALL" ) ;
42 
43  // for return codes
44  declareProperty( "Errors" , m_mode_err_s="NONE" ) ;
45 }
46 
47 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48 
52  m_log.setLevel( m_outputLevel.value() );
53 
54  if ( status.isFailure() ) { return status ; } // RETURN
55 
56  string key = m_mode_exc_s.value();
57 
58  auto loc = key.find(" ");
59  std::string mode = key.substr(0,loc);
60 
61  toupper(mode);
62 
63  if (mode == "NONE") { m_mode_exc = NONE;
64  } else if (mode == "ALL") { m_mode_exc = ALL;
65  } else {
66  m_log << MSG::ERROR << "Unknown mode for Exception handling: \"" << mode
67  << "\". Default must be one of \"ALL\" or \"NONE\"" << endmsg;
69  return StatusCode::FAILURE;
70  }
71 
72  if (loc == string::npos) {
73  key.clear();
74  } else {
75  key = key.substr(loc+1);
76  }
77 
78  std::string VAL, TAG;
79 
80  static const boost::regex exp{"[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*([^[:space:]]+)"};
81  static const auto tok_end = boost::sregex_iterator();
82  for (auto tok_iter = boost::sregex_iterator(begin(key), end(key), exp);
83  tok_iter != tok_end; ++tok_iter)
84  {
85  TAG = (*tok_iter)[1];
86  VAL = (*tok_iter)[2];
87  toupper(VAL);
88 
89  if (VAL == "SUCCESS") { m_retCodesExc[TAG] = SUCCESS;
90  } else if ( VAL == "FAILURE" ) { m_retCodesExc[TAG] = FAILURE;
91  } else if ( VAL == "REVOVERABLE" ) { m_retCodesExc[TAG] = RECOVERABLE;
92  } else if ( VAL == "RETHROW" ) { m_retCodesExc[TAG] = RETHROW;
93  } else if ( VAL == "DEFAULT" ) { m_retCodesExc[TAG] = DEFAULT;
94  } else {
95  m_log << MSG::ERROR << "In JobOpts: unknown return code \"" << VAL
96  << "\" for Algorithm " << TAG << std::endl
97  << " Must be one of: DEFAULT, SUCCESS, FAILURE, RECOVERABLE, RETHROW"
98  << endmsg;
100  return StatusCode::FAILURE;
101  }
102 
103  m_log << MSG::DEBUG << "Will catch exceptions thrown by: " << TAG
104  << " -> action: " << VAL << endmsg;
105 
106  }
107 
108  // now process errors
109  key = m_mode_err_s.value();
110 
111  loc = key.find(" ");
112  mode = key.substr(0,loc);
113 
114  toupper(mode);
115 
116  if (mode == "NONE") { m_mode_err = NONE;
117  } else if (mode == "ALL") { m_mode_err = ALL;
118  } else {
119  m_log << MSG::ERROR << "Unknown mode for Error handling: \"" << mode
120  << "\". Default must be one of \"ALL\" or \"NONE\"" << endmsg;
122  return StatusCode::FAILURE;
123  }
124 
125  if (loc == string::npos) {
126  key.clear();
127  } else {
128  key = key.substr(loc+1);
129  }
130 
131  for (auto tok_iter = boost::sregex_iterator(begin(key), end(key), exp);
132  tok_iter != tok_end; ++tok_iter)
133  {
134  TAG = (*tok_iter)[1];
135  VAL = (*tok_iter)[2];
136  toupper(VAL);
137 
138  if (VAL == "SUCCESS") { m_retCodesErr[TAG] = SUCCESS;
139  } else if ( VAL == "FAILURE" ) { m_retCodesErr[TAG] = FAILURE;
140  } else if ( VAL == "RECOVERABLE" ) { m_retCodesErr[TAG] = RECOVERABLE;
141  } else {
142  m_log << MSG::ERROR << "In JobOpts: unknown return code \"" << VAL
143  << "\" for Algorithm " << TAG << std::endl
144  << " Must be one of: SUCCESS, FAILURE, RECOVERABLE"
145  << endmsg;
147  return StatusCode::FAILURE;
148  }
149 
150  m_log << MSG::DEBUG << "Will process Errors returned by: " << TAG
151  << " -> action: " << VAL << endmsg;
152  }
153  return status;
154 }
155 
156 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
157 
159 ( const INamedInterface& alg ,
160  const StatusCode& st ) const
161 {
162  m_log << MSG::DEBUG << "Handling Error from " << alg.name() << endmsg;
163 
164  // is this Alg special?
165  auto i = m_retCodesErr.find(alg.name());
166  if ( i != m_retCodesErr.end()) {
167  switch ( i->second ) {
168  case SUCCESS: return StatusCode::SUCCESS;
169  case FAILURE: return StatusCode::FAILURE;
170  case RECOVERABLE: return StatusCode::RECOVERABLE;
171  // should never get here
172  case RETHROW: break;
173  case DEFAULT: break;
174  }
175 
176  } else {
177 
178  if (m_mode_err == ALL) return StatusCode::FAILURE; // turn it into FAILURE
179  assert (m_mode_err == NONE );
180  // don't touch the return code
181  return st;
182  }
183  return StatusCode::FAILURE;
184 }
185 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
186 
188 ( const INamedInterface& alg ) const
189 {
190 
191  // is this Alg special?
192  auto i = m_retCodesExc.find(alg.name());
193  if ( i != m_retCodesExc.end()) {
194 
195  switch ( i->second ) {
196  case DEFAULT: return StatusCode::FAILURE; // there is no default
197  case SUCCESS: return StatusCode::SUCCESS;
198  case FAILURE: return StatusCode::FAILURE;
199  case RECOVERABLE: return StatusCode::RECOVERABLE;
200  case RETHROW: throw;
201  }
202  }
203 
204  if (m_mode_exc == ALL) { throw; }
205  assert (m_mode_exc == NONE);
206  return StatusCode::FAILURE;
207 }
208 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
209 
211 ( const INamedInterface& alg ) const
212 {
213  m_log << MSG::DEBUG << "Handling unknown exception for " << alg.name()
214  << endmsg;
215  return process(alg);
216 }
217 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
218 
220 ( const INamedInterface& alg ,
221  const std::exception & exc ) const
222 {
223  m_log << MSG::DEBUG << "Handling std:except: \"" << exc.what() << "\" for "
224  << alg.name() << endmsg;
225  return process(alg) ;
226 }
227 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
228 
230 ( const INamedInterface& alg ,
231  const GaudiException & exc ) const
232 {
233  m_log << MSG::DEBUG << "Handling GaudiException: \"" << exc << "\" for "
234  << alg.name() << endmsg;
235  return process(alg);
236 }
237 
238 // ============================================================================
239 // The END
240 // ============================================================================
StatusCode initialize() override
Definition: Service.cpp:63
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
ExceptionSvc()=delete
no default constructor
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
std::map< std::string, ReturnState > m_retCodesErr
Definition: ExceptionSvc.h:65
STL namespace.
StatusCode handle(const INamedInterface &o, const GaudiException &e) const override
Handle caught GaudiExceptions.
Policy m_mode_exc
Definition: ExceptionSvc.h:63
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
virtual const std::string & name() const =0
Retrieve the name of the instance.
StringProperty m_mode_err_s
Definition: ExceptionSvc.h:64
int ALL
message levels --------------------------------------------------------—
Definition: Constants.py:11
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
Simple implementation of IExceptionSvc abstract interface.
Definition: ExceptionSvc.h:19
StringProperty m_mode_exc_s
Definition: ExceptionSvc.h:64
StatusCode initialize() override
initialize the service
const TYPE & value() const
explicit conversion
Definition: Property.h:341
StatusCode handleErr(const INamedInterface &o, const StatusCode &s) const override
Handle errors.
std::map< std::string, ReturnState > m_retCodesExc
Definition: ExceptionSvc.h:65
IInterface compliant class extending IInterface with the name() method.
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
void setLevel(int level)
Update outputlevel.
Definition: MsgStream.h:106
string s
Definition: gaudirun.py:245
Policy m_mode_err
Definition: ExceptionSvc.h:63
virtual StatusCode process(const INamedInterface &o) const
list i
Definition: ana.py:128
void toupper(std::string &s)
MsgStream m_log
Definition: ExceptionSvc.h:67