| # Gaudi Framework, version v21r9 |

Home |  | Generated: 3 May 2010

# ExceptionSvc.cpp

Go to the documentation of this file.

    00001 // $Id: ExceptionSvc.cpp,v 1.7 2008/06/02 14:21:35 marcocle Exp $
    00002 // ============================================================================
    00003 // CVS tag $Name:  $ , version $Revision: 1.7 $
    00004 // ============================================================================
    00005 // Include files
    00006 // ============================================================================
    00007 // STD & STL
    00008 // ============================================================================
    00009 #include <cassert>
    00010 #include <algorithm>
    00011 // ============================================================================
    00012 // GaudiKernel
    00013 // ============================================================================
    00014 #include "GaudiKernel/SvcFactory.h"
    00015 #include "GaudiKernel/ISvcLocator.h"
    00016 #include "GaudiKernel/Tokenizer.h"
    00017 // ============================================================================
    00018 //Local
    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   // for exceptions
    00045   declareProperty( "Catch"      , m_mode_exc_s="ALL" ) ;
    00046
    00047   // for return codes
    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 ; }                  // RETURN
    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   // now process errors
    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   // is this Alg special?
    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       // should never get here
    00231       break;
    00232     case DEFAULT:
    00233       // should never get here
    00234       break;
    00235     }
    00236
    00237   } else {
    00238
    00239     if (m_mode_err == ALL) {
    00240       // turn it into a FAILURE
    00241       return StatusCode::FAILURE;
    00242
    00243     } else {
    00244       assert (m_mode_err == NONE );
    00245       // don't touch the return code
    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   // is this Alg special?
    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       // there is no default
    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   // is this Alg special?
    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       // there is no default
    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   // is this Alg special?
    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 // The END
    00373 // ============================================================================