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