Gaudi Framework, version v21r8

Home   Generated: 17 Mar 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 // ============================================================================

Generated at Wed Mar 17 18:06:43 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004