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 : Service( 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
00216 ExceptionSvc::queryInterface
00217 ( const InterfaceID& iid ,
00218 void** ppvi )
00219 {
00220
00221 if ( 0 == ppvi ) { return StatusCode::FAILURE ; }
00222
00223 if ( IExceptionSvc::interfaceID().versionMatch( iid ) )
00224 { *ppvi = static_cast<IExceptionSvc*> ( this ) ; }
00225 else
00226 { return Service::queryInterface ( iid , ppvi ) ; }
00227
00228 addRef() ;
00229
00230 return StatusCode::SUCCESS ;
00231 }
00232
00233
00234
00235 StatusCode ExceptionSvc::handleErr
00236 ( const INamedInterface& alg ,
00237 const StatusCode& st ) const
00238 {
00239 m_log << MSG::DEBUG << "Handling Error from " << alg.name() << endmsg;
00240
00241
00242 if (m_retCodesErr.find(alg.name()) != m_retCodesErr.end()) {
00243 ReturnState iret = m_retCodesErr.find(alg.name())->second;
00244
00245 switch ( iret ) {
00246 case SUCCESS:
00247 return StatusCode::SUCCESS;
00248 case FAILURE:
00249 return StatusCode::FAILURE;
00250 case RECOVERABLE:
00251 return StatusCode::RECOVERABLE;
00252 case RETHROW:
00253
00254 break;
00255 case DEFAULT:
00256
00257 break;
00258 }
00259
00260 } else {
00261
00262 if (m_mode_err == ALL) {
00263
00264 return StatusCode::FAILURE;
00265
00266 } else {
00267 assert (m_mode_err == NONE );
00268
00269 return st;
00270 }
00271 }
00272
00273 return StatusCode::FAILURE;
00274
00275 }
00276
00277
00278 StatusCode ExceptionSvc::handle
00279 ( const INamedInterface& alg ) const
00280 {
00281 m_log << MSG::DEBUG << "Handling unknown exception for " << alg.name() << endmsg;
00282
00283
00284 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00285 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00286
00287 switch ( iret ) {
00288 case DEFAULT:
00289
00290 return StatusCode::FAILURE;
00291 case SUCCESS:
00292 return StatusCode::SUCCESS;
00293 case FAILURE:
00294 return StatusCode::FAILURE;
00295 case RECOVERABLE:
00296 return StatusCode::RECOVERABLE;
00297 case RETHROW:
00298 throw;
00299 }
00300
00301 } else {
00302
00303 if (m_mode_exc == ALL) {
00304 throw;
00305 } else {
00306 assert (m_mode_exc == NONE);
00307 return StatusCode::FAILURE;
00308 }
00309 }
00310
00311 return StatusCode::FAILURE;
00312
00313 }
00314
00315
00316 StatusCode ExceptionSvc::handle
00317 ( const INamedInterface& alg ,
00318 const std::exception & exc ) const
00319 {
00320 m_log << MSG::DEBUG << "Handling std:except for " << alg.name() << endmsg;
00321
00322
00323 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00324 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00325
00326 switch ( iret ) {
00327 case DEFAULT:
00328
00329 return StatusCode::FAILURE;
00330 case SUCCESS:
00331 return StatusCode::SUCCESS;
00332 case FAILURE:
00333 return StatusCode::FAILURE;
00334 case RECOVERABLE:
00335 return StatusCode::RECOVERABLE;
00336 case RETHROW:
00337 throw ( exc );
00338 }
00339
00340 } else {
00341
00342 if (m_mode_exc == ALL) {
00343 throw (exc);
00344 } else {
00345 assert (m_mode_exc == NONE);
00346 return StatusCode::FAILURE;
00347 }
00348 }
00349
00350 return StatusCode::FAILURE;
00351
00352 }
00353
00354
00355 StatusCode ExceptionSvc::handle
00356 ( const INamedInterface& alg ,
00357 const GaudiException & exc ) const
00358 {
00359
00360 m_log << MSG::DEBUG << "Handling GaudiExcept for " << alg.name() << endmsg;
00361
00362
00363 if (m_retCodesExc.find(alg.name()) != m_retCodesExc.end()) {
00364 ReturnState iret = m_retCodesExc.find(alg.name())->second;
00365
00366 switch ( iret ) {
00367 case DEFAULT:
00368 return exc.code();
00369 case SUCCESS:
00370 return StatusCode::SUCCESS;
00371 case FAILURE:
00372 return StatusCode::FAILURE;
00373 case RECOVERABLE:
00374 return StatusCode::RECOVERABLE;
00375 case RETHROW:
00376 throw ( exc );
00377 }
00378
00379 } else {
00380
00381 if (m_mode_exc == ALL) {
00382 throw (exc);
00383 } else {
00384 assert (m_mode_exc == NONE);
00385 return StatusCode::FAILURE;
00386 }
00387 }
00388
00389
00390 return StatusCode::FAILURE;
00391
00392 }
00393
00394
00395
00396