bes  Updated for version 3.20.6
BESDapError.cc
1 // BESDapError.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include <sstream>
34 #include <iostream>
35 
36 using std::ostringstream;
37 using std::endl;
38 
39 #include "BESDapError.h"
40 #include "BESContextManager.h"
41 #include "BESDapErrorInfo.h"
42 
43 #if 0
44 #include "BESInfoList.h"
45 #include "TheBESKeys.h"
46 #endif
47 
48 BESDapError::BESDapError(const string &s, bool fatal, libdap::ErrorCode ec, const string &file, int line) :
49  BESError(s, 0, file, line), d_dap_error_code(ec)
50 {
51  set_bes_error_type(convert_error_code(ec, fatal));
52 
53 #if 0
54  if (fatal)
55  set_bes_error_type(BES_INTERNAL_FATAL_ERROR);
56  else
57  set_bes_error_type(BES_INTERNAL_ERROR);
58 #endif
59 
60 }
61 
84 int BESDapError::convert_error_code(int error_code, int current_error_type)
85 {
86  if (current_error_type == BES_INTERNAL_FATAL_ERROR) return current_error_type;
87 
88  switch (error_code) {
89  case undefined_error:
90  case unknown_error: {
91  return BES_INTERNAL_ERROR;
92  break;
93  }
94  case internal_error: {
95  return BES_INTERNAL_FATAL_ERROR;
96  break;
97  }
98  case no_such_file: {
99  return BES_NOT_FOUND_ERROR;
100  break;
101  }
102  case no_such_variable:
103  case malformed_expr: {
104  return BES_SYNTAX_USER_ERROR;
105  break;
106  }
107  case no_authorization:
108  case cannot_read_file:
109  case dummy_message: {
110  return BES_FORBIDDEN_ERROR;
111  break;
112  }
113  default: {
114  return BES_INTERNAL_ERROR;
115  break;
116  }
117  }
118 }
119 
120 int BESDapError::convert_error_code(int error_code, bool fatal)
121 {
122  return convert_error_code(error_code, (fatal) ? BES_INTERNAL_FATAL_ERROR: BES_INTERNAL_ERROR);
123 }
124 
125 #if 0
126 void log_error(BESError &e)
127 {
128  string error_name = "";
129  // TODO This should be configurable; I'm changing the values below to always log all errors.
130  // I'm also confused about the actual intention. jhrg 11/14/17
131  bool only_log_to_verbose = false;
132  switch (e.get_bes_error_type()) {
133  case BES_INTERNAL_FATAL_ERROR:
134  error_name = "BES Internal Fatal Error";
135  break;
136 
137  case BES_INTERNAL_ERROR:
138  error_name = "BES Internal Error";
139  break;
140 
141  case BES_SYNTAX_USER_ERROR:
142  error_name = "BES User Syntax Error";
143  only_log_to_verbose = false; // TODO Was 'true.' jhrg 11/14/17
144  break;
145 
146  case BES_FORBIDDEN_ERROR:
147  error_name = "BES Forbidden Error";
148  break;
149 
150  case BES_NOT_FOUND_ERROR:
151  error_name = "BES Not Found Error";
152  only_log_to_verbose = false; // TODO was 'true.' jhrg 11/14/17
153  break;
154 
155  default:
156  error_name = "Unrecognized BES Error";
157  break;
158  }
159 
160  if (only_log_to_verbose) {
161  VERBOSE("ERROR: " << error_name << ", type: " << e.get_bes_error_type() << ", file: " << e.get_file() << ":"
162  << e.get_line() << ", message: " << e.get_message() << endl);
163 
164  }
165  else {
166  LOG("ERROR: " << error_name << ": " << e.get_message() << endl);
167  }
168 }
169 #endif
170 
171 
172 #if 0
173 
186 void BESDapError::add_ehm_callback(ptr_bes_ehm ehm)
187 {
188  _ehm_list.push_back(ehm);
189 }
190 #endif
191 
192 
193 #if 0
194 int BESDapError::handleBESError(BESError &e, BESDataHandlerInterface &dhi)
195 {
196  // Let's see if any of these exception callbacks can handle the
197  // exception. The first callback that can handle the exception wins
198  for (ehm_iter i = _ehm_list.begin(), ei = _ehm_list.end(); i != ei; ++i) {
199  ptr_bes_ehm p = *i;
200  int handled = p(e, dhi);
201  if (handled) {
202  return handled;
203  }
204  }
205 
206  dhi.error_info = BESInfoList::TheList()->build_info();
207  string action_name = dhi.action_name;
208  if (action_name.empty()) action_name = "BES";
209  dhi.error_info->begin_response(action_name, dhi);
210 
211  string administrator = "";
212  try {
213  bool found = false;
214  vector<string> vals;
215  string key = "BES.ServerAdministrator";
216  TheBESKeys::TheKeys()->get_value(key, administrator, found);
217  }
218  catch (...) {
219  administrator = DEFAULT_ADMINISTRATOR;
220  }
221  if (administrator.empty()) {
222  administrator = DEFAULT_ADMINISTRATOR;
223  }
224  dhi.error_info->add_exception(e, administrator);
225  dhi.error_info->end_response();
226 
227  // Write a message in the log file about this error...
228  log_error(e);
229 
230  return e.get_bes_error_type();
231 }
232 
242 int BESDapError::handleException(BESError &e, BESDataHandlerInterface &dhi)
243 {
244 <<<<<<< HEAD
245  // If we are handling errors in a dap2 context, then create a
246  // DapErrorInfo object to transmit/print the error as a dap2
247  // response.
248  bool found = false;
249  // I changed 'dap_format' to 'errors' in the following line. jhrg 10/6/08
250  string context = BESContextManager::TheManager()->get_context("errors", found);
251  if (context == "dap2" | context == "dap") {
252  ErrorCode ec = unknown_error;
253  BESDapError *de = dynamic_cast<BESDapError*>(&e);
254  if (de) {
255  ec = de->get_dap_error_code();
256  }
258  dhi.error_info = new BESDapErrorInfo(ec, e.get_message());
259 
260  return e.get_bes_error_type();
261  }
262  else {
263  // If we are not in a dap2 context and the exception is a dap
264  // handler exception, then convert the error message to include the
265  // error code. If it is or is not a dap exception, we simply return
266  // that the exception was not handled.
267  BESError *e_p = &e;
268  BESDapError *de = dynamic_cast<BESDapError*>(e_p);
269  if (de) {
270  ostringstream s;
271  s << "libdap exception building response: error_code = " << de->get_dap_error_code() << ": "
272  << de->get_message();
273  e.set_message(s.str());
275  }
276  }
277  return 0;
278 =======
279  // If we are handling errors in a dap2 context, then create a
280  // DapErrorInfo object to transmit/print the error as a dap2
281  // response.
282  bool found = false;
283  // I changed 'dap_format' to 'errors' in the following line. jhrg 10/6/08
284  string context = BESContextManager::TheManager()->get_context("errors", found);
285  if (context == "dap2") {
286  ErrorCode ec = unknown_error;
287  BESDapError *de = dynamic_cast<BESDapError*>(&e);
288  if (de) {
289  ec = de->get_dap_error_code();
290  }
292  dhi.error_info = new BESDapErrorInfo(ec, e.get_message());
293 
294  return e.get_bes_error_type();
295  }
296  else {
297  // If we are not in a dap2 context and the exception is a dap
298  // handler exception, then convert the error message to include the
299  // error code. If it is or is not a dap exception, we simply return
300  // that the exception was not handled.
301  BESError *e_p = &e;
302  BESDapError *de = dynamic_cast<BESDapError*>(e_p);
303  if (de) {
304  ostringstream s;
305  s << "libdap exception building response: error_code = " << de->get_dap_error_code() << ": "
306  << de->get_message();
307  e.set_message(s.str());
309  }
310  }
311 
312  return 0;
313 >>>>>>> master
314 }
315 #endif
316 
317 
324 void BESDapError::dump(ostream &strm) const
325 {
326  strm << BESIndent::LMarg << "BESDapError::dump - (" << (void *) this << ")" << endl;
327  BESIndent::Indent();
328  strm << BESIndent::LMarg << "error code = " << get_dap_error_code() << endl;
329  BESError::dump(strm);
330  BESIndent::UnIndent();
331 }
BESDapErrorInfo
silent informational response object
Definition: BESDapErrorInfo.h:50
BESError::get_bes_error_type
virtual int get_bes_error_type()
Return the return code for this error class.
Definition: BESError.h:143
BESError::get_line
virtual int get_line()
get the line number where the exception was thrown
Definition: BESError.h:115
BESError::get_message
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
BESError::get_file
virtual std::string get_file()
get the file name where the exception was thrown
Definition: BESError.h:107
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
BESInfo::add_exception
virtual void add_exception(BESError &e, const std::string &admin)
add exception information to this informational object
Definition: BESInfo.cc:234
BESDapError::dump
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESDapError.cc:324
TheBESKeys::get_value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:272
BESDapError::get_dap_error_code
virtual int get_dap_error_code() const
Definition: BESDapError.h:78
BESContextManager::get_context
virtual std::string get_context(const std::string &name, bool &found)
retrieve the value of the specified context from the BES
Definition: BESContextManager.cc:77
BESInfo::begin_response
virtual void begin_response(const std::string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:124
BESDapError
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
BESError::dump
virtual void dump(std::ostream &strm) const
Displays debug information about this object.
Definition: BESError.cc:59
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
BESDataHandlerInterface::error_info
BESInfo * error_info
error information object
Definition: BESDataHandlerInterface.h:94
BESDapError::convert_error_code
int convert_error_code(int error_code, int current_error_type)
converts the libdap error code to the bes error type
Definition: BESDapError.cc:84
BESError::set_bes_error_type
virtual void set_bes_error_type(int type)
Set the return code for this particular error class.
Definition: BESError.h:132
BESError::set_message
virtual void set_message(const std::string &msg)
set the error message for this exception
Definition: BESError.h:91