Gaudi Framework, version v21r6

Home   Generated: 11 Nov 2009

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   : Service( 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
00216 ExceptionSvc::queryInterface
00217 ( const InterfaceID&  iid  ,
00218   void**              ppvi )
00219 {
00220   // invalid placeholder
00221   if ( 0 == ppvi ) { return StatusCode::FAILURE   ; }   // RETURN
00222   // check the identidier
00223   if ( IExceptionSvc::interfaceID().versionMatch( iid ) )
00224   { *ppvi = static_cast<IExceptionSvc*>  ( this ) ; }  // OK !
00225   else  // ask for base class
00226   { return Service::queryInterface ( iid , ppvi ) ; }  // RETURN
00227   // increment the reference counter
00228   addRef() ;
00229   //
00230   return StatusCode::SUCCESS ;                        // RETURN
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   // is this Alg special?
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       // should never get here
00254       break;
00255     case DEFAULT:
00256       // should never get here
00257       break;
00258     }
00259 
00260   } else {
00261 
00262     if (m_mode_err == ALL) {
00263       // turn it into a FAILURE
00264       return StatusCode::FAILURE;
00265 
00266     } else {
00267       assert (m_mode_err == NONE );
00268       // don't touch the return code
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   // is this Alg special?
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       // there is no default
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   // is this Alg special?
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       // there is no default
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   // is this Alg special?
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 // The END
00396 // ============================================================================

Generated at Wed Nov 11 16:23:11 2009 for Gaudi Framework, version v21r6 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004