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