00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <new>
00024
00025 #include "safeerrno.h"
00026 #ifdef __WIN32__
00027 # include "safewindows.h"
00028 #else
00029 # include <netdb.h>
00030 #endif
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035
00036 #include <xapian/error.h>
00037
00038 #include "utils.h"
00039
00040 using namespace std;
00041
00042 Xapian::Error::Error(const std::string &msg_, const std::string &context_,
00043 const char * type_, const char * error_string_)
00044 : msg(msg_), context(context_), type(type_), my_errno(0),
00045 error_string(), already_handled(false)
00046 {
00047 if (error_string_) error_string.assign(error_string_);
00048 }
00049
00050 const char *
00051 Xapian::Error::get_error_string() const
00052 {
00053 if (!error_string.empty()) return error_string.c_str();
00054 if (my_errno == 0) return NULL;
00055 if (my_errno > 0) {
00056 error_string.assign(strerror(my_errno));
00057 return error_string.c_str();
00058 }
00059 #ifdef __WIN32__
00060 DWORD len;
00061 char * error;
00062 len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
00063 0, -my_errno, 0, (CHAR*)&error, 0, 0);
00064 if (error) {
00065
00066 if (len >= 2 && error[len - 2] == '\r' && error[len - 1] == '\n')
00067 len -= 2;
00068 error_string.assign(error, len);
00069 LocalFree(error);
00070 return error_string.c_str();
00071 }
00072 #else
00073 # ifdef HAVE_HSTRERROR
00074 error_string.assign(hstrerror(-my_errno));
00075 return error_string.c_str();
00076 # else
00077 const char * s = NULL;
00078 switch (-my_errno) {
00079 case HOST_NOT_FOUND:
00080 s = "Unknown host";
00081 break;
00082 case NO_ADDRESS:
00083 # if NO_ADDRESS != NO_DATA
00084 case NO_DATA:
00085 # endif
00086 s = "No address associated with name";
00087 break;
00088 case NO_RECOVERY:
00089 s = "Unknown server error";
00090 break;
00091 case TRY_AGAIN:
00092 s = "Host name lookup failure";
00093 break;
00094 }
00095 if (s) {
00096 error_string.assign(s);
00097 return error_string.c_str();
00098 }
00099 # endif
00100 #endif
00101
00102 #ifndef HAVE_HSTRERROR
00103 error_string = "Unknown Error ";
00104 error_string += om_tostring(-my_errno);
00105 return error_string.c_str();
00106 #endif
00107 }
00108
00109 string
00110 Xapian::Error::get_description() const
00111 {
00112 string desc(type);
00113 desc += ": ";
00114 desc += msg;
00115 if (!context.empty()) {
00116 desc += " (context: ";
00117 desc += context;
00118 desc += ')';
00119 }
00120 const char *e = get_error_string();
00121 if (e) {
00122 desc += " (";
00123 desc += e;
00124 desc += ')';
00125 }
00126 return desc;
00127 }