00001 // BESExceptionManager.cc 00002 00003 // This file is part of bes, A C++ back-end server implementation framework 00004 // for the OPeNDAP Data Access Protocol. 00005 00006 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research 00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu> 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Lesser General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2.1 of the License, or (at your option) any later version. 00013 // 00014 // This library is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // Lesser General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU Lesser General Public 00020 // License along with this library; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 // 00023 // You can contact University Corporation for Atmospheric Research at 00024 // 3080 Center Green Drive, Boulder, CO 80301 00025 00026 // (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005 00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR. 00028 // 00029 // Authors: 00030 // pwest Patrick West <pwest@ucar.edu> 00031 // jgarcia Jose Garcia <jgarcia@ucar.edu> 00032 00033 #include "BESExceptionManager.h" 00034 00035 #include "BESDatabaseException.h" 00036 #include "BESContainerStorageException.h" 00037 #include "BESKeysException.h" 00038 #include "BESLogException.h" 00039 #include "BESHandlerException.h" 00040 #include "BESIncorrectRequestException.h" 00041 #include "BESResponseException.h" 00042 #include "BESTransmitException.h" 00043 #include "BESAggregationException.h" 00044 00045 #include "BESStatusReturn.h" 00046 #include "TheBESKeys.h" 00047 #include "BESInfoList.h" 00048 00049 #define DEFAULT_ADMINISTRATOR "support@unidata.ucar.edu" 00050 00051 BESExceptionManager *BESExceptionManager::_instance = 0 ; 00052 00053 BESExceptionManager::BESExceptionManager() 00054 { 00055 } 00056 00057 BESExceptionManager::~BESExceptionManager() 00058 { 00059 } 00060 00061 void 00062 BESExceptionManager::add_ehm_callback( p_bes_ehm ehm ) 00063 { 00064 _ehm_list.push_back( ehm ) ; 00065 } 00066 00083 int 00084 BESExceptionManager::handle_exception( BESException &e, 00085 BESDataHandlerInterface &dhi ) 00086 { 00087 // Let's see if any of these exception callbacks can handle the 00088 // exception. The first callback that can handle the exception wins 00089 ehm_iter i = _ehm_list.begin() ; 00090 for( ; i != _ehm_list.end(); i++ ) 00091 { 00092 p_bes_ehm p = *i ; 00093 int handled = p( e, dhi ) ; 00094 if( handled ) 00095 { 00096 return handled ; 00097 } 00098 } 00099 00100 dhi.error_info = BESInfoList::TheList()->build_info() ; 00101 string action_name = dhi.action_name ; 00102 if( action_name == "" ) 00103 action_name = "BES" ; 00104 dhi.error_info->begin_response( action_name ) ; 00105 00106 string administrator = "" ; 00107 try 00108 { 00109 bool found = false ; 00110 administrator = 00111 TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ; 00112 } 00113 catch( ... ) 00114 { 00115 administrator = DEFAULT_ADMINISTRATOR ; 00116 } 00117 dhi.error_info->add_tag( "Administrator", administrator ) ; 00118 dhi.error_info->add_exception( e ) ; 00119 dhi.error_info->end_response() ; 00120 return e.get_return_code() ; 00121 00122 /* Replaced with the above three lines 00123 BESIncorrectRequestException *ireqx=dynamic_cast<BESIncorrectRequestException*>(&e); 00124 if( ireqx ) 00125 { 00126 dhi.error_info->add_exception( "Request", e ) ; 00127 dhi.error_info->end_response() ; 00128 return BES_REQUEST_INCORRECT; 00129 } 00130 BESDatabaseException *ce=dynamic_cast<BESDatabaseException*>(&e); 00131 if(ce) 00132 { 00133 dhi.error_info->add_exception( "Database", e ) ; 00134 dhi.error_info->end_response() ; 00135 return BES_DATABASE_FAILURE; 00136 } 00137 BESContainerStorageException *dpe=dynamic_cast<BESContainerStorageException*>(&e); 00138 if(dpe) 00139 { 00140 dhi.error_info->add_exception( "ContainerStore", e ) ; 00141 dhi.error_info->end_response() ; 00142 return BES_CONTAINER_PERSISTENCE_ERROR; 00143 } 00144 BESKeysException *keysex=dynamic_cast<BESKeysException*>(&e); 00145 if(keysex) 00146 { 00147 dhi.error_info->add_exception( "Configuration", e ) ; 00148 dhi.error_info->end_response() ; 00149 return BES_INITIALIZATION_FILE_PROBLEM; 00150 } 00151 BESLogException *logex=dynamic_cast<BESLogException*>(&e); 00152 if(logex) 00153 { 00154 dhi.error_info->add_exception( "Log", e ) ; 00155 dhi.error_info->end_response() ; 00156 return BES_LOG_FILE_PROBLEM; 00157 } 00158 BESHandlerException *hanex=dynamic_cast <BESHandlerException*>(&e); 00159 if(hanex) 00160 { 00161 dhi.error_info->add_exception( "DataHandlerProblem", e ) ; 00162 dhi.error_info->end_response() ; 00163 return BES_DATA_HANDLER_PROBLEM; 00164 } 00165 BESResponseException *ranex=dynamic_cast <BESResponseException*>(&e); 00166 if(ranex) 00167 { 00168 dhi.error_info->add_exception( "DataHandlerFailure", e ) ; 00169 dhi.error_info->end_response() ; 00170 return BES_DATA_HANDLER_FAILURE; 00171 } 00172 BESTransmitException *transex=dynamic_cast <BESTransmitException*>(&e); 00173 if(transex) 00174 { 00175 dhi.error_info->add_exception( "TransmitProblem", e ) ; 00176 dhi.error_info->end_response() ; 00177 return BES_DATA_HANDLER_PROBLEM; 00178 } 00179 BESAggregationException *aanex=dynamic_cast <BESAggregationException*>(&e); 00180 if(aanex) 00181 { 00182 dhi.error_info->add_exception( "Aggregation", e ) ; 00183 dhi.error_info->end_response() ; 00184 return BES_AGGREGATION_EXCEPTION ; 00185 } 00186 00187 dhi.error_info->add_exception( "Unknown", e ) ; 00188 dhi.error_info->end_response() ; 00189 return BES_TERMINATE_IMMEDIATE; 00190 */ 00191 } 00192 00202 void 00203 BESExceptionManager::dump( ostream &strm ) const 00204 { 00205 strm << BESIndent::LMarg << "BESExceptionManager::dump - (" 00206 << (void *)this << ")" << endl ; 00207 BESIndent::Indent() ; 00208 strm << BESIndent::LMarg << "# registered callbacks: " << _ehm_list.size() << endl ; 00209 BESIndent::UnIndent() ; 00210 } 00211 00212 BESExceptionManager * 00213 BESExceptionManager::TheEHM() 00214 { 00215 if( _instance == 0 ) 00216 { 00217 _instance = new BESExceptionManager( ) ; 00218 } 00219 return _instance ; 00220 } 00221