Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

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 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:24:54 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004