libzypp  17.22.0
networkrequesterror.cc
Go to the documentation of this file.
4 #include <zypp/base/Gettext.h>
6 #include <curl/curl.h>
7 
8 namespace zyppng {
9 
10 ZYPP_IMPL_PRIVATE(NetworkRequestError);
11 
12 NetworkRequestErrorPrivate::NetworkRequestErrorPrivate(NetworkRequestError::Type code, std::string &&msg, std::map<std::string, boost::any> &&extraInfo)
13  : _errorCode(code)
14  , _errorMessage( std::move(msg) )
15 , _extraInfo( std::move(extraInfo) )
16 { }
17 
19 {
20  return new NetworkRequestErrorPrivate( *this );
21 }
22 
23 NetworkRequestError NetworkRequestErrorPrivate::customError( NetworkRequestError::Type t, std::string &&errorMsg, std::map<std::string, boost::any> &&extraInfo )
24 {
25  return NetworkRequestError( *new NetworkRequestErrorPrivate(t, errorMsg.empty() ? typeToString(t) : std::move(errorMsg), std::move(extraInfo)) );
26 }
27 
29 {
30 
31  Url url = req.url();
33  std::string err;
34  std::map<std::string, boost::any> extraInfo;
35 
36  if ( nativeCode != 0 ) {
37 
38  const char *nativeErr = curl_easy_strerror( static_cast<CURLcode>(nativeCode) );
39  if ( nativeErr != nullptr )
40  extraInfo.insert( { "nativeErrorCodeDesc", std::string( nativeErr ) } );
41 
42  if ( errBuf != nullptr )
43  extraInfo.insert( { "nativeErrorDesc", std::string( errBuf ) } );
44 
45  extraInfo.insert( { "requestUrl", url } );
46  extraInfo.insert( { "curlCode", nativeCode } );
47  extraInfo.insert( { "filepath", req.targetFilePath().asString() } );
48  extraInfo.insert( { "lastRedirect", req.lastRedirectInfo() } );
49 
50  switch ( nativeCode )
51  {
52  case CURLE_UNSUPPORTED_PROTOCOL:
54  err = typeToString( c );
55  if ( !req.lastRedirectInfo().empty() )
56  {
57  err += " or redirect (";
58  err += req.lastRedirectInfo();
59  err += ")";
60  }
61  break;
62  case CURLE_URL_MALFORMAT: case CURLE_URL_MALFORMAT_USER:
64  break;
65  case CURLE_LOGIN_DENIED:
67  break;
68  case CURLE_HTTP_RETURNED_ERROR: {
69  long httpReturnCode = 0;
70  CURLcode infoRet = curl_easy_getinfo( req.nativeHandle(),
71  CURLINFO_RESPONSE_CODE,
72  &httpReturnCode );
73 
74  if ( infoRet == CURLE_OK ) {
75  extraInfo.insert( { "responseCode", httpReturnCode } );
76 
77  std::string msg = "HTTP response: " + zypp::str::numstring( httpReturnCode );
78  switch ( httpReturnCode )
79  {
80  case 401: {
81  std::string auth_hint;
82  {
83  long auth_info = CURLAUTH_NONE;
84 
85  CURLcode infoRet =
86  curl_easy_getinfo(req.nativeHandle(), CURLINFO_HTTPAUTH_AVAIL, &auth_info);
87 
88  if(infoRet == CURLE_OK) {
89  extraInfo.insert( { "authHint", zypp::media::CurlAuthData::auth_type_long2str(auth_info) } );
90  }
91  }
92 
93  //if there is already a user:password entry in the settings the auth simply failed
94  //@TODO write a testcase for this
95  if ( !req.transferSettings().userPassword().empty() ) {
97  } else {
99  }
100 
101  break;
102  }
103 
104  case 502: // bad gateway (bnc #1070851)
105  case 503: // service temporarily unavailable (bnc #462545)
107  err = zypp::str::form( _("Location '%s' is temporarily unaccessible."), url.asString().c_str() );
108  break;
109  case 504: // gateway timeout
111  err = zypp::str::form(_("Timeout exceeded when accessing '%s'."), url.asString().c_str() );
112  break;
113  case 403: {
114  std::string msg403;
115  if ( url.getHost().find(".suse.com") != std::string::npos )
116  msg403 = _("Visit the SUSE Customer Center to check whether your registration is valid and has not expired.");
117  else if (url.asString().find("novell.com") != std::string::npos)
118  msg403 = _("Visit the Novell Customer Center to check whether your registration is valid and has not expired.");
119 
121  err = msg403;
122  break;
123  }
124  case 404:
125  case 410:
127  err = zypp::str::form( _("File '%s' not found on medium '%s'"), req.targetFilePath().c_str(), url.asString().c_str() );
128  break;
129 
130  default:
132  err = zypp::str::form(_("Download (curl) error for '%s':\n"
133  "Error code: %s\n"), url.asString().c_str(), zypp::str::numstring( httpReturnCode ).c_str() ) ;
134  break;
135  }
136  } else {
138  err = zypp::str::form(_("Download (curl) error for '%s':\n"
139  "Unable to retrieve HTTP response\n"), url.asString().c_str() ) ;
140  }
141  }
142  break;
143  case CURLE_FTP_COULDNT_RETR_FILE:
144 #if CURLVERSION_AT_LEAST(7,16,0)
145  case CURLE_REMOTE_FILE_NOT_FOUND:
146 #endif
147  case CURLE_FTP_ACCESS_DENIED:
148  case CURLE_TFTP_NOTFOUND:
150  break;
151  case CURLE_BAD_PASSWORD_ENTERED:
152  case CURLE_FTP_USER_PASSWORD_INCORRECT:
154  break;
155  case CURLE_COULDNT_RESOLVE_PROXY:
156  case CURLE_COULDNT_RESOLVE_HOST:
157  case CURLE_COULDNT_CONNECT:
158  case CURLE_FTP_CANT_GET_HOST:
160  break;
161  case CURLE_WRITE_ERROR:
163  break;
164  case CURLE_PARTIAL_FILE:
165  case CURLE_OPERATION_TIMEDOUT:
167  break;
168  case CURLE_ABORTED_BY_CALLBACK:
170  break;
171  case CURLE_PEER_FAILED_VERIFICATION:
173  break;
174  default:
176  err = "Curl error " + zypp::str::numstring( nativeCode );
177  break;
178  }
179  }
180 
181  if ( err.empty() )
182  err = typeToString( c );
183 
184  return NetworkRequestError( *new NetworkRequestErrorPrivate(c, std::move(err), std::move(extraInfo)) );
185 }
186 
188 {
189  const char *nativeErr = curl_multi_strerror( static_cast<CURLMcode>(nativeCode) );
190 
191  std::map<std::string, boost::any> extraInfo;
192  extraInfo.insert( { "curlMCode", nativeCode } );
193 
194  std::string err;
195  if ( nativeErr == nullptr )
196  err = "The dispatcher returned an unknown error";
197  else
198  err = std::string( nativeErr );
199 
200  return NetworkRequestError( *new NetworkRequestErrorPrivate(NetworkRequestError::InternalError, std::move(err), std::move(extraInfo)) );
201 }
202 
203 
205  : d_ptr( &d )
206 { }
207 
209  : d_ptr( new NetworkRequestErrorPrivate( NoError, {}, {} ) )
210 { }
211 
213 {
214  return d_func()->_errorCode;
215 }
216 
217 std::string NetworkRequestError::toString() const
218 {
219  return d_func()->_errorMessage;
220 }
221 
223 {
224  return d_func()->_errorCode != NoError;
225 }
226 
227 const std::map<std::string, boost::any> &NetworkRequestError::extraInfo() const
228 {
229  return d_func()->_extraInfo;
230 }
231 
233 {
234  switch ( t ) {
236  return "No error";
238  return "Internal Error";
240  return "The request was cancelled";
242  return "The request exceeded the maximum download size";
244  return "The downloaded data did not result in a valid checksum";
246  return "The peer certificate could not be verified";
248  return "Connection failed";
250  return "Unsupported protocol";
252  return "Bad URL";
254  return "Requested location is temporarily unaccessible.";
256  return "Timeout reached";
258  return "Access to requested URL is forbidden.";
260  return "File not found";
262  return "Authentication required but not provided.";
264  return "Login failed.";
266  return "Server returned an error for the given request.";
267  }
268  return std::string();
269 }
270 
272 {
273  Z_D();
274 
275  auto it = d->_extraInfo.find("nativeErrorDesc");
276  if ( it != d->_extraInfo.end() ) {
277  try {
278  return boost::any_cast<std::string>( it->second );
279  } catch ( const boost::bad_any_cast &) { }
280  }
281 
282  it = d->_extraInfo.find("nativeErrorCodeDesc");
283  if ( it != d->_extraInfo.end() ) {
284  try {
285  return boost::any_cast<std::string>( it->second );
286  } catch ( const boost::bad_any_cast &) { }
287  }
288 
289  return std::string();
290 }
291 
292 }
Interface to gettext.
bool isError() const
isError Will return true if this is a actual error
void * nativeHandle() const
Definition: request.cc:536
const std::string & lastRedirectInfo() const
Definition: request.cc:531
static zyppng::NetworkRequestError fromCurlMError(int nativeCode)
const char * c_str() const
String representation.
Definition: Pathname.h:110
std::string toString() const
toString Returns a string representation of the error
Definition: Arch.h:347
Url url
Definition: MediaCurl.cc:65
std::string nativeErrorString() const
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
TransferSettings & transferSettings()
Definition: request.cc:607
#define Z_D()
Definition: zyppglobal.h:44
static std::string typeToString(NetworkRequestError::Type t)
const std::map< std::string, boost::any > & extraInfo() const
const std::string & asString() const
String representation.
Definition: Pathname.h:91
NetworkRequestErrorPrivate(NetworkRequestError::Type code, std::string &&msg, std::map< std::string, boost::any > &&extraInfo)
The NetworkRequestError class Represents a error that occured in.
#define _(MSG)
Definition: Gettext.h:37
std::string numstring(char n, int w=0)
Definition: String.h:286
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition: request.cc:561
static std::string auth_type_long2str(long auth_type)
Converts a long of ORed CURLAUTH_* identifiers into a string of comma separated list of authenticatio...
static zyppng::NetworkRequestError fromCurlError(NetworkRequest &req, int nativeCode, const char *errBuf)
Type type() const
type Returns the type of the error
std::string userPassword() const
returns the user and password as a user:pass string
ZYPP_IMPL_PRIVATE(NetworkRequestError)
NetworkRequestErrorPrivate * clone() const
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
Convenience interface for handling authentication data of media user.
Url manipulation class.
Definition: Url.h:87