| # Gaudi Framework, version v21r7p1 |

Home |  | Generated: 15 Feb 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 // ============================================================================
    00011 // GaudiKernel
    00012 // ============================================================================
    00013 #include "GaudiKernel/SvcFactory.h"
    00014 #include "GaudiKernel/ISvcLocator.h"
    00015 #include "GaudiKernel/Tokenizer.h"
    00016 // ============================================================================
    00017 //Local
    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   // for exceptions
    00048   declareProperty( "Catch"      , m_mode_exc_s="ALL" ) ;
    00049
    00050   // for return codes
    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 ; }                  // RETURN
    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   // now process errors
    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   // is this Alg special?
    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       // should never get here
    00234       break;
    00235     case DEFAULT:
    00236       // should never get here
    00237       break;
    00238     }
    00239
    00240   } else {
    00241
    00242     if (m_mode_err == ALL) {
    00243       // turn it into a FAILURE
    00244       return StatusCode::FAILURE;
    00245
    00246     } else {
    00247       assert (m_mode_err == NONE );
    00248       // don't touch the return code
    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   // is this Alg special?
    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       // there is no default
    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   // is this Alg special?
    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       // there is no default
    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   // is this Alg special?
    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 // The END
    00376 // ============================================================================