1 /*
2  * This File is part of Davix, The IO library for HTTP based protocols
3  * Copyright (C) CERN 2013
4  * Author: Adrien Devresse <adrien.devresse@cern.ch>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20 */
21 
22 #ifndef DAVIX_DAVIXSTATUSREQUEST_HPP
23 #define DAVIX_DAVIXSTATUSREQUEST_HPP
24 
25 #include <string>
26 #include <utils/davix_types.hpp>
27 #include <iostream>
28 
29 /**
30   @file davixstatusrequest.hpp
31   @author Devresse Adrien, CERN
32 
33   @brief Error report system of davix
34 */
35 
36 #ifndef __DAVIX_INSIDE__
37 #error "Only davix.h or davix.hpp should be included."
38 #endif
39 
40 
41 namespace Davix {
42 
43 class Context;
44 class NGQRequest;
45 struct DavixErrorInternal;
46 
47 namespace StatusCode{
48 
49 
50 
51 /// Common Error code of Davix
52 /// See \ref DavixError for more details
53 ///
54 enum Code {
55     /// No Error report
56     OK = 0x000,
57 
58     /// Request executed partially
59     PartialDone = 0x001,
60 
61     /// Error in the Webdav properties parsing
62     WebDavPropertiesParsingError = 0x002,
63 
64     /// Error in the Webdav properties parsing
65     UriParsingError = 0x003,
66 
67     /// impossible to create a session
68     SessionCreationError = 0x004,
69 
70     /// DNS resolution failure
71     NameResolutionFailure= 0x005,
72 
73     /// Impossible to connect, host down or network problem
74     ConnectionProblem = 0x006,
75 
76     /// redirection is needed manually
77     RedirectionNeeded = 0x007,
78 
79     /// Impossible to connect, host down or network problem
80     ConnectionTimeout = 0x008,
81 
82     /// operation timeout
83     OperationTimeout = 0x009,
84 
85     /// this operation is not supported
86     OperationNonSupported= 0x00a,
87 
88     /// Action impossible, is a directory or a collection
89     IsNotADirectory = 0x00b,
90 
91     /// Invalid file descriptor
92     InvalidFileHandle = 0x00c,
93 
94     /// Request already running
95     AlreadyRunning = 0x00d,
96 
97     /// Authentication Error
98     AuthenticationError= 0x00e,
99 
100     /// Wrong Login and/or Password
101     LoginPasswordError = 0x00f,
102 
103     /// Impossible to find specified credential
104     CredentialNotFound = 0x010,
105 
106     /// Permission deny, Authorisation problem ( EACCESS, EPERM )
107     PermissionRefused = 0x011,
108 
109     /// File not found (ENOENT )
110     FileNotFound = 0x012,
111 
112     /// This file is not a regular file but a directory ( EISDIR )
113     IsADirectory = 0x013,
114 
115     /// System call related error
116     SystemError = 0x014,
117 
118     /// File already exist ( EEXIST )
119     FileExist = 0x015,
120 
121     /// Invalid argument from user ( EINVAL )
122     InvalidArgument = 0x016,
123 
124     /// Server answer problem ( > 500 )
125     InvalidServerResponse = 0x017,
126 
127     /// SSL/TLS layer Error
128     SSLError = 0x018,
129 
130     /// Impossible to decrypt client credential for usage
131     CredDecryptionError = 0x019,
132 
133     /// Operation canceled
134     Canceled = 0x020,
135 
136     /// Delegation error
137     DelegationError = 0x021,
138 
139     /// Remote error. Used for third party copies: it means the
140     /// destination failed.
141     RemoteError = 0x022,
142 
143     /// Generic Parsing Error
144     ParsingError = 0x23,
145 
146     /// Invalid Hook type
147     InvalidHook = 0x24,
148 
149     /// Connection timeout during a redirection
150     TimeoutRedirectionError = 0x25,
151 
152     /// Too many redirects
153     TooManyRedirects = 0x26,
154 
155     /// Insufficient storage
156     InsufficientStorage = 0x27,
157 
158     /// Undefined error
159     UnknowError = 0x100
160 
161 
162 };
163 
164 }
165 
166 ///  @class DavixError
167 ///  @brief Davix Error Handler
168 ///
169 /// Error report system of Davix, similar behavior to the Glib Error report
170 /// Davix does not use C++ exception
171 ///
172 ///
173 /// Each function which takes a DavixError** as argument can take the value NULL
174 ///
175 /// Example :
176 ///
177 ///
178 class DAVIX_EXPORT DavixError{
179 public:
180 
181     ///
182     /// Construct a DavixError object
183     ///
184     /// @param scope : string parameter representing the scope of the error
185     /// @param errCode : Davix Error code, see  Davix::StatusCode::Code
186     /// @param errMsg : String representation of the error
187     DavixError(const std::string & scope, StatusCode::Code errCode, const std::string & errMsg);
188     ///
189     /// \brief copy constructor
190     /// \param e
191     ///
192     DavixError(const DavixError & e);
193     ///
194     /// \brief assignment operator
195     /// \param e
196     /// \return
197     ///
198     DavixError & operator=(const DavixError & e);
199     ///
200     /// \brief ~DavixError
201     ///
202     virtual ~DavixError();
203 
204 
205     ///
206     /// \brief clone Error
207     /// \return new dynamically allocated copy of the Error
208     ///
209     DavixError* clone();
210 
211     ///
212     /// @return Davix status code of the error
213     StatusCode::Code getStatus() const;
214 
215     ///
216     /// set the status code for this error
217     void setStatus(const StatusCode::Code);
218 
219     ///
220     /// get the string representation of this error
221     const std::string & getErrMsg() const;
222 
223     ///
224     /// set the string representation of this error
225     void setErrMsg(const std::string & msg);
226 
227     ///
228     /// set the scope of this error
229     void setErrScope(const std::string & scope);
230 
231     ///
232     /// get the scope of this error
233     const std::string & getErrScope() const;
234 
235 
236 
237     ///
238     /// \brief create a new DavixError
239     /// \param err pointer to a DavixError pointer
240     /// \param scope scope of the Error
241     /// \param errCode Error code
242     /// \param errMsg Error message
243     ///
244     ///
245     /// create a new dynamically allocated DavixError Object
246     /// if err is NULL, silent suppress the error report
247     static void setupError(DavixError** err, const std::string & scope, StatusCode::Code errCode, const std::string & errMsg);
248 
249     ///
250     /// clear the content of the current error and set err to NULL
251     static void clearError(DavixError** err);
252 
253 
254 
255     ///
256     /// \brief propagate an Error structure to an upper level
257     /// \param newErr
258     /// \param oldErr
259     ///
260     ///  propagate the Davix Error Object from oldErr to newErr
261     ///  OldErr can be consider as free after this operation
262     ///  erase the current error if newErr is not NULL
263     ///
264     static void propagateError(DavixError** newErr, DavixError* oldErr);
265 
266 
267     ////
268     /// \brief swap the two error content
269     /// \param err
270     ///
271     void swap(DavixError & err);
272 
273 
274     ///
275     /// \brief propagatePrefixedError
276     /// \param newErr
277     /// \param oldErr
278     /// \param prefix
279     ///
280     /// same than propagateError but add a string prefix in front of the error description
281     ///
282     //////
283     static void propagatePrefixedError(DavixError** newErr, DavixError* oldErr, const std::string & prefix);
284 
285 private:
286    DavixErrorInternal * d_ptr;
287 };
288 
289 
290 
291 ///  @class DavixException
292 ///  @brief Davix Exception class
293 ///
294 /// Contain a Davix Error
295 ///
296 ///
297 class DAVIX_EXPORT DavixException : public std::exception{
298     struct DavixExceptionIntern;
299 public:
300     /// Construct a DavixException
301     DavixException(const std::string & scope, StatusCode::Code c, const std::string & msg) throw();
302 
303     /// Create a DavixEception from a DavixError, err is considered as free and invalid after creation
304     DavixException(DavixError** err);
305 
306     /// Copy Constructor
307     DavixException(const DavixException & orig) throw();
308 
309     virtual ~DavixException() throw();
310 
311     /// return a string representation of the scope for this davix exception
312     virtual const char* scope() const throw();
313 
314     /// return the error code association to this DavixException, same than @ref DavixError::getStatus()
315     virtual StatusCode::Code code() const throw();
316 
317     /// return a string representation or the error
318     virtual const char*  what() const throw();
319 
320     /// Extract a DavixError from this exception
321     void toDavixError(DavixError** err);
322 
323 protected:
324     DavixError e;
325     DavixExceptionIntern* d_ptr;
326 };
327 
328 
329 void checkDavixError(DavixError** err);
330 
331 
332 #define TRY_DAVIX try
333 #define CATCH_DAVIX(err) catch(DavixException & e){ \
334         e.toDavixError(err); \
335     }catch(std::exception & e){ \
336         DavixError::setupError(err, " ", StatusCode::SystemError, std::string("System Error ").append(e.what())); \
337     }catch(...){ \
338         DavixError::setupError(err, " ", StatusCode::UnknowError, std::string("Unknow Error .... report this")); \
339     }
340 
341 
342 /// \cond PRIVATE_SYMBOLS
343 ///
344 DAVIX_EXPORT std::string davix_scope_stat_str();
345 DAVIX_EXPORT std::string davix_scope_davOps_str();
346 DAVIX_EXPORT std::string davix_scope_mkdir_str();
347 DAVIX_EXPORT std::string davix_scope_rm_str();
348 DAVIX_EXPORT std::string davix_scope_mv_str();
349 DAVIX_EXPORT std::string davix_scope_directory_listing_str();
350 DAVIX_EXPORT std::string davix_scope_http_request();
351 DAVIX_EXPORT std::string davix_scope_meta();
352 DAVIX_EXPORT std::string davix_scope_xml_parser();
353 DAVIX_EXPORT std::string davix_scope_uri_parser();
354 DAVIX_EXPORT std::string davix_scope_io_buff();
355 DAVIX_EXPORT std::string davix_scope_x509cred();
356 
357 
358 
359 //
360 DAVIX_EXPORT void davix_errno_to_davix_error(int errcode, const std::string & scope, const std::string & msg, DavixError** newErr);
361 
362 DAVIX_EXPORT void errno_to_davix_exception(int errno_code, const std::string & scope, const std::string & msg);
363 
364 
365 
366 
367 
368 
369 
370 
371 
372 
373 
374 
375 
376 
377 
378 
379 
380 
381 
382 
383 
384 // !!!!!!!!!!!!!!!!!!!
385 // Warning: Deprecated symbols, do not use anymore
386 // /////////////////////////////////////////////////
387 // Deprecated, do not use, API compability only
388 namespace StatusCode{
389 const Code AuthentificationError = AuthenticationError;
390 }
391 
392 typedef enum StatusCode::Code davix_status_t;
393 
394 
395 /// \endcond PRIVATE_SYMBOLS
396 
397 } // namespace Davix
398 
399 
400 #endif // DAVIX_DAVIXSTATUSREQUEST_H
401