ExceptionSvc.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <cassert>
00010
00011
00012
00013 #include "GaudiKernel/SvcFactory.h"
00014 #include "GaudiKernel/ISvcLocator.h"
00015 #include "GaudiKernel/Tokenizer.h"
00016
00017
00018
00019 #include "ExceptionSvc.h"
00020
00021
00022 using namespace std;
00023
00024
00025
00026 DECLARE_SERVICE_FACTORY(ExceptionSvc)
00027
00028 inline void toupper(std::string &s)
00029 {
00030 std::string::iterator it=s.begin();
00031 while(it != s.end())
00032 {
00033 *it = toupper(*it);
00034 it++;
00035 }
00036 }
00037
00038
00040
00041
00042 ExceptionSvc::ExceptionSvc( const std::string& name, ISvcLocator* svc )
00043 : base_class( name, svc )
00044 , m_mode_exc ( ALL ), m_mode_err( NONE )
00045 , m_log(msgSvc(), name )
00046 {
00047
00048 declareProperty( "Catch" , m_mode_exc_s="ALL" ) ;
00049
00050
00051 declareProperty( "Errors" , m_mode_err_s="NONE" ) ;
00052 }
00053
00054
00055
00056 ExceptionSvc::~ExceptionSvc() {
00057
00058 }
00059
00060
00061
00062
00063 StatusCode
00064 ExceptionSvc::initialize() {
00065 StatusCode status = Service::initialize();
00066 m_log.setLevel( m_outputLevel.value() );
00067
00068 if ( status.isFailure() ) { return status ; }
00069
00070 string key = m_mode_exc_s.value();
00071
00072 string::size_type loc = key.find(" ");
00073 std::string mode;
00074 if (loc == std::string::npos) {
00075 mode = key;
00076 } else {
00077 mode = key.substr(0,loc);
00078 }
00079
00080 toupper(mode);
00081
00082 if (mode == "NONE") {
00083 m_mode_exc = NONE;
00084 } else if (mode == "ALL") {
00085 m_mode_exc = ALL;
00086 } else {
00087 m_log << MSG::ERROR << "Unknown mode for Exception handling: \"" << mode
00088 << "\". Default must be one of \"ALL\" or \"NONE\"" << endmsg;
00089 m_state = Gaudi::StateMachine::OFFLINE;
00090 return StatusCode::FAILURE;
00091 }
00092
00093 if (loc == string::npos) {
00094 key = "";
00095 } else {
00096 key = key.substr(loc+1,key.length());
00097 }
00098
00099 Tokenizer tok(true);
00100 std::string val,VAL,TAG;
00101
00102 tok.analyse( key, " ", "", "", "=", "", "");
00103
00104 for ( Tokenizer::Items::iterator i = tok.items().begin();
00105 i != tok.items().end(); i++) {
00106 const std::string& tag = (*i).tag();
00107 TAG = tag;
00108
00109 val = (*i).value();
00110 VAL = val;
00111 toupper(VAL);
00112
00113 if (VAL == "SUCCESS") {
00114 m_retCodesExc[TAG] = SUCCESS;
00115 } else if ( VAL == "FAILURE" ) {
00116 m_retCodesExc[TAG] = FAILURE;
00117 } else if ( VAL == "REVOVERABLE" ) {
00118 m_retCodesExc[TAG] = RECOVERABLE;
00119 } else if ( VAL == "RETHROW" ) {
00120 m_retCodesExc[TAG] = RETHROW;
00121 } else if ( VAL == "DEFAULT" ) {
00122 m_retCodesExc[TAG] = DEFAULT;
00123 } else {
00124 m_log << MSG::ERROR << "In JobOpts: unknown return code \"" << VAL
00125 << "\" for Algorithm " << TAG << std::endl
00126 << " Must be one of: DEFAULT, SUCCESS, FAILURE, RECOVERABLE, RETHROW"
00127 << endmsg;
00128 m_state = Gaudi::StateMachine::OFFLINE;
00129 return StatusCode::FAILURE;
00130 }
00131
00132 m_log << MSG::DEBUG << "Will catch exceptions thrown by: " << TAG
00133 << " -> action: " << VAL << endmsg;
00134
00135 }
00136
00137
00138
00139 key = m_mode_err_s.value();
00140
00141 loc = key.find(" ");
00142 if (loc == std::string::npos) {
00143 mode = key;
00144 } else {
00145 mode = key.substr(0,loc);
00146 }
00147
00148 toupper(mode);
00149
00150 if (mode == "NONE") {
00151 m_mode_err = NONE;
00152 } else if (mode == "ALL") {
00153 m_mode_err = ALL;
00154 } else {
00155 m_log << MSG::ERROR << "Unknown mode for Error handling: \"" << mode
00156 << "\". Default must be one of \"ALL\" or \"NONE\"" << endmsg;
00157 m_state = Gaudi::StateMachine::OFFLINE;
00158 return StatusCode::FAILURE;
00159 }
00160
00161 if (loc == string::npos) {
00162 key = "";
00163 } else {
00164 key = key.substr(loc+1,key.length());
00165 }
00166
00167 Tokenizer tok2(true);
00168 tok2.analyse( key, " ", "", "", "=", "", "");
00169
00170 for ( Tokenizer::Items::iterator i = tok2.items().begin();
00171 i != tok2.items().end(); i++) {
00172 const std::string& tag = (*i).tag();
00173 TAG = tag;
00174
00175 val = (*i).value();
00176 VAL = val;
00177 toupper(VAL);
00178
00179 if (VAL == "SUCCESS") {
00180 m_retCodesErr[TAG] = SUCCESS;
00181 } else if ( VAL == "FAILURE" ) {
00182 m_retCodesErr[TAG] = FAILURE;
00183 } else if ( VAL == "RECOVERABLE" ) {
00184 m_retCodesErr[TAG] = RECOVERABLE;
00185 } else {
00186 m_log << MSG::ERROR << "In JobOpts: unknown return code \"" << VAL
00187 << "\" for Algorithm " << TAG << std::endl
00188 << " Must be one of: SUCCESS, FAILURE, RECOVERABLE"
00189 << endmsg;
00190 m_state = Gaudi::StateMachine::OFFLINE;
00191 return StatusCode::FAILURE;
00192 }
00193
00194 m_log << MSG::DEBUG << "Will process Errors returned by: " << TAG
00195 << " -> action: " << VAL << endmsg;
00196
00197 }
00198
00199
00200
00201 return status;
00202 }
00203
00204
00205
00206 StatusCode
00207 ExceptionSvc::finalize() {
00208 StatusCode status = Service::finalize();
00209
00210 return status;
00211 }
00212
00213
00214
00215 StatusCode ExceptionSvc::handleErr
00216 ( const INamedInterface& alg ,
00217 const StatusCode& st ) const
00218 {
00219 m_log << MSG::DEBUG << "Handling Error from " << alg.name() << endmsg;
00220
00221
00222 if (m_retCodesErr.find(alg.name()) != m_retCodesErr.end()) {
00223 ReturnState iret = m_retCodesErr.find(alg.name())->second;
00224
00225 switch ( iret ) {
00226 case SUCCESS:
00227 return StatusCode::SUCCESS;
00228 case FAILURE:
00229 return StatusCode::FAILURE;
00230 case RECOVERABLE:
00231 return StatusCode::RECOVERABLE;
00232 case RETHROW:
00233
00234 break;
00235 case DEFAULT:
00236
00237 break;
00238 }
00239
00240 } else {
00241
00242 if (m_mode_err == ALL) {
00243
00244 return StatusCode::FAILURE;
00245
00246 } else {
00247 assert (m_mode_err == NONE );
00248
00249 return st;
00250 }
00251 }
00252
00253 return StatusCode::FAILURE;
00254
00255 }
00256
00257
00258 StatusCode ExceptionSvc::handle
00259 ( const INamedInterface& alg ) const
00260 {
00261 m_log << MSG::DEBUG << "Handling unknown exception for " << alg.name() << endmsg;
00262
00263
00264 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00265 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00266
00267 switch ( iret ) {
00268 case DEFAULT:
00269
00270 return StatusCode::FAILURE;
00271 case SUCCESS:
00272 return StatusCode::SUCCESS;
00273 case FAILURE:
00274 return StatusCode::FAILURE;
00275 case RECOVERABLE:
00276 return StatusCode::RECOVERABLE;
00277 case RETHROW:
00278 throw;
00279 }
00280
00281 } else {
00282
00283 if (m_mode_exc == ALL) {
00284 throw;
00285 } else {
00286 assert (m_mode_exc == NONE);
00287 return StatusCode::FAILURE;
00288 }
00289 }
00290
00291 return StatusCode::FAILURE;
00292
00293 }
00294
00295
00296 StatusCode ExceptionSvc::handle
00297 ( const INamedInterface& alg ,
00298 const std::exception & exc ) const
00299 {
00300 m_log << MSG::DEBUG << "Handling std:except for " << alg.name() << endmsg;
00301
00302
00303 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00304 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00305
00306 switch ( iret ) {
00307 case DEFAULT:
00308
00309 return StatusCode::FAILURE;
00310 case SUCCESS:
00311 return StatusCode::SUCCESS;
00312 case FAILURE:
00313 return StatusCode::FAILURE;
00314 case RECOVERABLE:
00315 return StatusCode::RECOVERABLE;
00316 case RETHROW:
00317 throw ( exc );
00318 }
00319
00320 } else {
00321
00322 if (m_mode_exc == ALL) {
00323 throw (exc);
00324 } else {
00325 assert (m_mode_exc == NONE);
00326 return StatusCode::FAILURE;
00327 }
00328 }
00329
00330 return StatusCode::FAILURE;
00331
00332 }
00333
00334
00335 StatusCode ExceptionSvc::handle
00336 ( const INamedInterface& alg ,
00337 const GaudiException & exc ) const
00338 {
00339
00340 m_log << MSG::DEBUG << "Handling GaudiExcept for " << alg.name() << endmsg;
00341
00342
00343 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00344 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00345
00346 switch ( iret ) {
00347 case DEFAULT:
00348 return exc.code();
00349 case SUCCESS:
00350 return StatusCode::SUCCESS;
00351 case FAILURE:
00352 return StatusCode::FAILURE;
00353 case RECOVERABLE:
00354 return StatusCode::RECOVERABLE;
00355 case RETHROW:
00356 throw ( exc );
00357 }
00358
00359 } else {
00360
00361 if (m_mode_exc == ALL) {
00362 throw (exc);
00363 } else {
00364 assert (m_mode_exc == NONE);
00365 return StatusCode::FAILURE;
00366 }
00367 }
00368
00369
00370 return StatusCode::FAILURE;
00371
00372 }
00373
00374
00375
00376