bes  Updated for version 3.20.5
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 
38 #include "BESDapError.h"
39 #include "BESContextManager.h"
40 #include "BESDapErrorInfo.h"
41 
42 #if 0
43 #include "BESInfoList.h"
44 #include "TheBESKeys.h"
45 #endif
46 
47 BESDapError::BESDapError(const string &s, bool fatal, libdap::ErrorCode ec, const string &file, int line) :
48  BESError(s, 0, file, line), d_dap_error_code(ec)
49 {
50  set_bes_error_type(convert_error_code(ec, fatal));
51 
52 #if 0
53  if (fatal)
54  set_bes_error_type(BES_INTERNAL_FATAL_ERROR);
55  else
56  set_bes_error_type(BES_INTERNAL_ERROR);
57 #endif
58 
59 }
60 
83 int BESDapError::convert_error_code(int error_code, int current_error_type)
84 {
85  if (current_error_type == BES_INTERNAL_FATAL_ERROR) return current_error_type;
86 
87  switch (error_code) {
88  case undefined_error:
89  case unknown_error: {
90  return BES_INTERNAL_ERROR;
91  break;
92  }
93  case internal_error: {
94  return BES_INTERNAL_FATAL_ERROR;
95  break;
96  }
97  case no_such_file: {
98  return BES_NOT_FOUND_ERROR;
99  break;
100  }
101  case no_such_variable:
102  case malformed_expr: {
103  return BES_SYNTAX_USER_ERROR;
104  break;
105  }
106  case no_authorization:
107  case cannot_read_file:
108  case dummy_message: {
109  return BES_FORBIDDEN_ERROR;
110  break;
111  }
112  default: {
113  return BES_INTERNAL_ERROR;
114  break;
115  }
116  }
117 }
118 
119 int BESDapError::convert_error_code(int error_code, bool fatal)
120 {
121  return convert_error_code(error_code, (fatal) ? BES_INTERNAL_FATAL_ERROR: BES_INTERNAL_ERROR);
122 }
123 
124 #if 0
125 void log_error(BESError &e)
126 {
127  string error_name = "";
128  // TODO This should be configurable; I'm changing the values below to always log all errors.
129  // I'm also confused about the actual intention. jhrg 11/14/17
130  bool only_log_to_verbose = false;
131  switch (e.get_bes_error_type()) {
132  case BES_INTERNAL_FATAL_ERROR:
133  error_name = "BES Internal Fatal Error";
134  break;
135 
136  case BES_INTERNAL_ERROR:
137  error_name = "BES Internal Error";
138  break;
139 
140  case BES_SYNTAX_USER_ERROR:
141  error_name = "BES User Syntax Error";
142  only_log_to_verbose = false; // TODO Was 'true.' jhrg 11/14/17
143  break;
144 
145  case BES_FORBIDDEN_ERROR:
146  error_name = "BES Forbidden Error";
147  break;
148 
149  case BES_NOT_FOUND_ERROR:
150  error_name = "BES Not Found Error";
151  only_log_to_verbose = false; // TODO was 'true.' jhrg 11/14/17
152  break;
153 
154  default:
155  error_name = "Unrecognized BES Error";
156  break;
157  }
158 
159  if (only_log_to_verbose) {
160  VERBOSE("ERROR: " << error_name << ", type: " << e.get_bes_error_type() << ", file: " << e.get_file() << ":"
161  << e.get_line() << ", message: " << e.get_message() << endl);
162 
163  }
164  else {
165  LOG("ERROR: " << error_name << ": " << e.get_message() << endl);
166  }
167 }
168 #endif
169 
170 
171 #if 0
172 
185 void BESDapError::add_ehm_callback(ptr_bes_ehm ehm)
186 {
187  _ehm_list.push_back(ehm);
188 }
189 #endif
190 
191 
192 #if 0
193 int BESDapError::handleBESError(BESError &e, BESDataHandlerInterface &dhi)
194 {
195  // Let's see if any of these exception callbacks can handle the
196  // exception. The first callback that can handle the exception wins
197  for (ehm_iter i = _ehm_list.begin(), ei = _ehm_list.end(); i != ei; ++i) {
198  ptr_bes_ehm p = *i;
199  int handled = p(e, dhi);
200  if (handled) {
201  return handled;
202  }
203  }
204 
205  dhi.error_info = BESInfoList::TheList()->build_info();
206  string action_name = dhi.action_name;
207  if (action_name.empty()) action_name = "BES";
208  dhi.error_info->begin_response(action_name, dhi);
209 
210  string administrator = "";
211  try {
212  bool found = false;
213  vector<string> vals;
214  string key = "BES.ServerAdministrator";
215  TheBESKeys::TheKeys()->get_value(key, administrator, found);
216  }
217  catch (...) {
218  administrator = DEFAULT_ADMINISTRATOR;
219  }
220  if (administrator.empty()) {
221  administrator = DEFAULT_ADMINISTRATOR;
222  }
223  dhi.error_info->add_exception(e, administrator);
224  dhi.error_info->end_response();
225 
226  // Write a message in the log file about this error...
227  log_error(e);
228 
229  return e.get_bes_error_type();
230 }
231 
241 int BESDapError::handleException(BESError &e, BESDataHandlerInterface &dhi)
242 {
243 <<<<<<< HEAD
244  // If we are handling errors in a dap2 context, then create a
245  // DapErrorInfo object to transmit/print the error as a dap2
246  // response.
247  bool found = false;
248  // I changed 'dap_format' to 'errors' in the following line. jhrg 10/6/08
249  string context = BESContextManager::TheManager()->get_context("errors", found);
250  if (context == "dap2" | context == "dap") {
251  ErrorCode ec = unknown_error;
252  BESDapError *de = dynamic_cast<BESDapError*>(&e);
253  if (de) {
254  ec = de->get_dap_error_code();
255  }
257  dhi.error_info = new BESDapErrorInfo(ec, e.get_message());
258 
259  return e.get_bes_error_type();
260  }
261  else {
262  // If we are not in a dap2 context and the exception is a dap
263  // handler exception, then convert the error message to include the
264  // error code. If it is or is not a dap exception, we simply return
265  // that the exception was not handled.
266  BESError *e_p = &e;
267  BESDapError *de = dynamic_cast<BESDapError*>(e_p);
268  if (de) {
269  ostringstream s;
270  s << "libdap exception building response: error_code = " << de->get_dap_error_code() << ": "
271  << de->get_message();
272  e.set_message(s.str());
274  }
275  }
276  return 0;
277 =======
278  // If we are handling errors in a dap2 context, then create a
279  // DapErrorInfo object to transmit/print the error as a dap2
280  // response.
281  bool found = false;
282  // I changed 'dap_format' to 'errors' in the following line. jhrg 10/6/08
283  string context = BESContextManager::TheManager()->get_context("errors", found);
284  if (context == "dap2") {
285  ErrorCode ec = unknown_error;
286  BESDapError *de = dynamic_cast<BESDapError*>(&e);
287  if (de) {
288  ec = de->get_dap_error_code();
289  }
291  dhi.error_info = new BESDapErrorInfo(ec, e.get_message());
292 
293  return e.get_bes_error_type();
294  }
295  else {
296  // If we are not in a dap2 context and the exception is a dap
297  // handler exception, then convert the error message to include the
298  // error code. If it is or is not a dap exception, we simply return
299  // that the exception was not handled.
300  BESError *e_p = &e;
301  BESDapError *de = dynamic_cast<BESDapError*>(e_p);
302  if (de) {
303  ostringstream s;
304  s << "libdap exception building response: error_code = " << de->get_dap_error_code() << ": "
305  << de->get_message();
306  e.set_message(s.str());
308  }
309  }
310 
311  return 0;
312 >>>>>>> master
313 }
314 #endif
315 
316 
323 void BESDapError::dump(ostream &strm) const
324 {
325  strm << BESIndent::LMarg << "BESDapError::dump - (" << (void *) this << ")" << endl;
326  BESIndent::Indent();
327  strm << BESIndent::LMarg << "error code = " << get_dap_error_code() << endl;
328  BESError::dump(strm);
329  BESIndent::UnIndent();
330 }
int convert_error_code(int error_code, int current_error_type)
converts the libdap error code to the bes error type
Definition: BESDapError.cc:83
silent informational response object
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
virtual void dump(std::ostream &strm) const
Displays debug information about this object.
Definition: BESError.cc:59
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:420
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESDapError.cc:323
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
virtual void add_exception(BESError &e, const string &admin)
add exception information to this informational object
Definition: BESInfo.cc:234
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
virtual int get_dap_error_code() const
Definition: BESDapError.h:78
virtual void set_message(const std::string &msg)
set the error message for this exception
Definition: BESError.h:91
Structure storing information used by the BES to handle the request.
virtual std::string get_file()
get the file name where the exception was thrown
Definition: BESError.h:107
virtual void set_bes_error_type(int type)
Set the return code for this particular error class.
Definition: BESError.h:132
virtual int get_bes_error_type()
Return the return code for this error class.
Definition: BESError.h:143
virtual void begin_response(const string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:124
BESInfo * error_info
error information object
virtual int get_line()
get the line number where the exception was thrown
Definition: BESError.h:115