Branch data Line data Source code
1 : : /** @file error.cc
2 : : * @brief Xapian::Error base class.
3 : : */
4 : : /* Copyright (C) 2007,2008,2011,2013,2014,2015 Olly Betts
5 : : *
6 : : * This program is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU General Public License as
8 : : * published by the Free Software Foundation; either version 2 of the
9 : : * License, or (at your option) any later version.
10 : : *
11 : : * This program is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this program; if not, write to the Free Software
18 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : : */
20 : :
21 : : #include <config.h>
22 : :
23 : : #include <xapian/error.h>
24 : :
25 : : #ifdef __WIN32__
26 : : # include "safewindows.h"
27 : : #else
28 : : # include "safenetdb.h"
29 : : #endif
30 : :
31 : : #include <cerrno>
32 : : #include <cstdlib> // For abs().
33 : : #include <cstring> // For memcmp().
34 : :
35 : : #include "errno_to_string.h"
36 : : #include "str.h"
37 : : #include "unicode/description_append.h"
38 : :
39 : : using namespace std;
40 : :
41 : 24195 : Xapian::Error::Error(const std::string &msg_, const std::string &context_,
42 : : const char * type_, const char * error_string_)
43 : : : msg(msg_), context(context_), error_string(), type(type_),
44 [ + - ][ + - ]: 24195 : my_errno(0)
45 : : {
46 [ + + ][ + - ]: 24195 : if (error_string_) error_string.assign(error_string_);
47 : 24195 : }
48 : :
49 : : const char *
50 : 24210 : Xapian::Error::get_error_string() const
51 : : {
52 [ + + ]: 24210 : if (error_string.empty()) {
53 [ + + ]: 24205 : if (my_errno == 0) return NULL;
54 : : #ifdef __WIN32__
55 : : if (my_errno < 0 || my_errno >= WSABASEERR) {
56 : : int e = abs(my_errno);
57 : : DWORD len;
58 : : char * error;
59 : : len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|
60 : : FORMAT_MESSAGE_ALLOCATE_BUFFER,
61 : : 0, e, 0, (CHAR*)&error, 0, 0);
62 : : if (error) {
63 : : // Remove any trailing \r\n from output of FormatMessage.
64 : : if (len >= 2 && memcmp(error + len - 2, "\r\n", 2) == 0)
65 : : len -= 2;
66 : : error_string.assign(error, len);
67 : : LocalFree(error);
68 : : } else {
69 : : error_string = "Unknown Error ";
70 : : error_string += str(e);
71 : : }
72 : : } else {
73 : : errno_to_string(my_errno, error_string);
74 : : }
75 : : #else
76 [ + - ]: 9 : if (my_errno > 0) {
77 : 9 : errno_to_string(my_errno, error_string);
78 : : } else {
79 : : // POSIX says only that EAI_* constants are "non-zero" - they're
80 : : // negative on Linux, but we allow for them being positive. We
81 : : // check they all that the same sign in net/remoteconnection.h.
82 : : if (EAI_FAIL > 0)
83 : : error_string.assign(gai_strerror(-my_errno));
84 : : else
85 : 9 : error_string.assign(gai_strerror(my_errno));
86 : : }
87 : : #endif
88 : : }
89 : 14 : return error_string.c_str();
90 : : }
91 : :
92 : : string
93 : 9 : Xapian::Error::get_description() const
94 : : {
95 [ + - ]: 9 : string desc(get_type());
96 [ + - ]: 9 : desc += ": ";
97 [ + - ]: 9 : desc += msg;
98 [ + + ]: 9 : if (!context.empty()) {
99 [ + - ]: 1 : desc += " (context: ";
100 [ + - ]: 1 : description_append(desc, context);
101 [ + - ]: 1 : desc += ')';
102 : : }
103 [ + - ]: 9 : const char *e = get_error_string();
104 [ + + ]: 9 : if (e) {
105 [ + - ]: 1 : desc += " (";
106 [ + - ][ + - ]: 1 : description_append(desc, e);
107 [ + - ]: 1 : desc += ')';
108 : : }
109 : 9 : return desc;
110 : : }
|