bes Updated for version 3.20.10
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
36using std::ostringstream;
37using 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
48BESDapError::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
84int 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
120int 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
126void 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
186void BESDapError::add_ehm_callback(ptr_bes_ehm ehm)
187{
188 _ehm_list.push_back(ehm);
189}
190#endif
191
192
193#if 0
194int 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
242int 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
324void 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}
virtual std::string get_context(const std::string &name, bool &found)
retrieve the value of the specified context from the BES
silent informational response object
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
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
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESDapError.cc:324
virtual int get_dap_error_code() const
Definition: BESDapError.h:78
Structure storing information used by the BES to handle the request.
BESInfo * error_info
error information object
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
virtual int get_bes_error_type()
Return the return code for this error class.
Definition: BESError.h:143
virtual void set_bes_error_type(int type)
Set the return code for this particular error class.
Definition: BESError.h:132
virtual int get_line()
get the line number where the exception was thrown
Definition: BESError.h:115
virtual void dump(std::ostream &strm) const
Displays debug information about this object.
Definition: BESError.cc:59
virtual std::string get_file()
get the file name where the exception was thrown
Definition: BESError.h:107
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
virtual void set_message(const std::string &msg)
set the error message for this exception
Definition: BESError.h:91
virtual void begin_response(const std::string &response_name, BESDataHandlerInterface &dhi)
begin the informational response
Definition: BESInfo.cc:124
virtual void add_exception(BESError &e, const std::string &admin)
add exception information to this informational object
Definition: BESInfo.cc:234
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:340
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:71