1 #ifndef CORELIB___NCBIERROR__HPP
2 #define CORELIB___NCBIERROR__HPP
3 
4 /*  $Id: ncbierror.hpp 566948 2018-07-10 19:41:29Z lavr $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author:  Andrei Gourianov
30  *
31  *
32  */
33 
34 /// @file ncbierror.hpp
35 /// Defines NCBI C++ Toolkit portable error codes.
36 
37 #include <corelib/ncbimisc.hpp>
38 #include <errno.h>
39 #include <corelib/impl/ncbierror_impl.hpp>
40 
41 
42 /** @addtogroup Exception
43  *
44  * @{
45  */
46 
47 BEGIN_NCBI_SCOPE
48 
49 
50 class NCBI_XNCBI_EXPORT CNcbiError
51 {
52 public:
53     enum ECode {
54         eNotSet                         = -1,
55         eSuccess                        = 0,
56 
57         /// Generic error codes are set based on errno error codes.
58         eAddressFamilyNotSupported      = EAFNOSUPPORT,
59         eAddressInUse                   = EADDRINUSE,
60         eAddressNotAvailable            = EADDRNOTAVAIL,
61         eAlreadyConnected               = EISCONN,
62         eArgumentListTooLong            = E2BIG,
63         eArgumentOutOfDomain            = EDOM,
64         eBadAddress                     = EFAULT,
65         eBadFileDescriptor              = EBADF,
66         eBadMessage                     = EBADMSG,
67         eBrokenPipe                     = EPIPE,
68         eConnectionAborted              = ECONNABORTED,
69         eConnectionAlreadyInProgress    = EALREADY,
70         eConnectionRefused              = ECONNREFUSED,
71         eConnectionReset                = ECONNRESET,
72         eCrossDeviceLink                = EXDEV,
73         eDestinationAddressRequired     = EDESTADDRREQ,
74         eDeviceOrResourceBusy           = EBUSY,
75         eDirectoryNotEmpty              = ENOTEMPTY,
76         eExecutableFormatError          = ENOEXEC,
77         eFileExists                     = EEXIST,
78         eFileTooLarge                   = EFBIG,
79         eFilenameTooLong                = ENAMETOOLONG,
80         eFunctionNotSupported           = ENOSYS,
81         eHostUnreachable                = EHOSTUNREACH,
82         eIdentifierRemoved              = EIDRM,
83         eIllegalByteSequence            = EILSEQ,
84         eInappropriateIoControlOperation= ENOTTY,
85         eInterrupted                    = EINTR,
86         eInvalidArgument                = EINVAL,
87         eInvalidSeek                    = ESPIPE,
88         eIoError                        = EIO,
89         eIsADirectory                   = EISDIR,
90         eMessageSize                    = EMSGSIZE,
91         eNetworkDown                    = ENETDOWN,
92         eNetworkReset                   = ENETRESET,
93         eNetworkUnreachable             = ENETUNREACH,
94         eNoBufferSpace                  = ENOBUFS,
95         eNoChildProcess                 = ECHILD,
96         eNoLink                         = ENOLINK,
97         eNoLockAvailable                = ENOLCK,
98 //        eNoMessageAvailable             = ENODATA,
99         eNoMessage                      = ENOMSG,
100         eNoProtocolOption               = ENOPROTOOPT,
101         eNoSpaceOnDevice                = ENOSPC,
102 //        eNoStreamResources              = ENOSR,
103         eNoSuchDeviceOrAddress          = ENXIO,
104         eNoSuchDevice                   = ENODEV,
105         eNoSuchFileOrDirectory          = ENOENT,
106         eNoSuchProcess                  = ESRCH,
107         eNotADirectory                  = ENOTDIR,
108         eNotASocket                     = ENOTSOCK,
109 //        eNotAStream                     = ENOSTR,
110         eNotConnected                   = ENOTCONN,
111         eNotEnoughMemory                = ENOMEM,
112         eNotSupported                   = ENOTSUP,
113         eOperationCanceled              = ECANCELED,
114         eOperationInProgress            = EINPROGRESS,
115         eOperationNotPermitted          = EPERM,
116         eOperationNotSupported          = EOPNOTSUPP,
117         eOperationWouldBlock            = EWOULDBLOCK,
118 //        eOwnerDead                      = EOWNERDEAD,
119         ePermissionDenied               = EACCES,
120         eProtocolError                  = EPROTO,
121         eProtocolNotSupported           = EPROTONOSUPPORT,
122         eReadOnlyFileSystem             = EROFS,
123         eResourceDeadlockWouldOccur     = EDEADLK,
124         eResourceUnavailableTryAgain    = EAGAIN,
125         eResultOutOfRange               = ERANGE,
126 //        eStateNotRecoverable            = ENOTRECOVERABLE,
127 //        eStreamTimeout                  = ETIME,
128         eTextFileBusy                   = ETXTBSY,
129         eTimedOut                       = ETIMEDOUT,
130         eTooManyFilesOpenInSystem       = ENFILE,
131         eTooManyFilesOpen               = EMFILE,
132         eTooManyLinks                   = EMLINK,
133         eTooManySymbolicLinkLevels      = ELOOP,
134         eValueTooLarge                  = EOVERFLOW,
135         eWrongProtocolType              = EPROTOTYPE,
136 
137         /// Unknown error
138         eUnknown = 0x1000
139 
140         /// NCBI-specific error codes
141     };
142 
143     /// Error code category.
144     enum ECategory {
145         eGeneric   = 0,
146         eNcbi      = 1,
147         eMsWindows = 2
148     };
149 
150     /// Get error code.
151     ECode Code(void) const;
152 
153     /// Get error code category.
Category(void) const154     ECategory Category(void) const {
155         return m_Category;
156     }
157 
158     /// Get native numeric value of the error.
Native(void) const159     int Native(void) const {
160         return m_Native;
161     }
162 
163     /// Get string information provided when this error was set.
Extra(void) const164     const string& Extra(void) const {
165         return m_Extra;
166     }
167 
168     /// Copy constructor
CNcbiError(const CNcbiError & err)169     CNcbiError(const CNcbiError& err)
170         : m_Code(err.m_Code),
171           m_Category(err.m_Category),
172           m_Native(err.m_Native),
173           m_Extra(err.m_Extra)
174     {}
175 
~CNcbiError(void)176     ~CNcbiError(void) {}
177 
178     /// Assignment.
operator =(const CNcbiError & err)179     CNcbiError& operator= (const CNcbiError& err) {
180         m_Code     = err.m_Code;
181         m_Category = err.m_Category;
182         m_Native   = err.m_Native;
183         m_Extra    = err.m_Extra;
184         return *this;
185     }
186 
187     /// Comparison.
operator ==(ECode err) const188     bool operator== (ECode err) const {
189         return Code() == err;
190     }
191 
192     /// Operator bool: returns TRUE if error was not set to "success"
193     DECLARE_OPERATOR_BOOL(Code() != eSuccess);
194 
195     /// Get the error that was last set (in the current thread)
196     /// @sa Set(), SetErrno(), SetFromErrno(), SetWindowsError()
197     /// @sa SetFromWindowsError()
198     static const CNcbiError& GetLast(void);
199 
200     /// Set last error using native error code enum
201     ///
202     /// @param code
203     ///   Error code
204     /// @param extra
205     ///   Additional information
206     static void Set(ECode code);
207     /// @copydoc CNcbiError::Set(ECode)
208     static void Set(ECode code, const CTempString extra);
209     /// @copydoc CNcbiError::Set(ECode)
210     static void Set(ECode code, const char* extra);
211     /// @copydoc CNcbiError::Set(ECode)
212     static void Set(ECode code, const string& extra);
213     /// @copydoc CNcbiError::Set(ECode)
214     static void Set(ECode code, string&& extra);
215 
216     /// Set last error using errno code
217     ///
218     /// @param errno_code
219     ///   "errno" code
220     /// @param extra
221     ///   Additional information
222     static void SetErrno(int errno_code);
223     /// @copydoc CNcbiError::SetErrno(int)
224     static void SetErrno(int errno_code, const CTempString extra);
225     /// @copydoc CNcbiError::SetErrno(int)
226     static void SetErrno(int errno_code, const string& extra);
227     /// @copydoc CNcbiError::SetErrno(int)
228     static void SetErrno(int errno_code, const char* extra);
229     /// @copydoc CNcbiError::SetErrno(int)
230     static void SetErrno(int errno_code, string&& extra);
231 
232     /// Set last error using current "errno" code
233     ///
234     /// @param extra
235     ///   Additional information
236     static void SetFromErrno(void);
237     /// @copydoc CNcbiError::SetFromErrno(void)
238     static void SetFromErrno(const CTempString extra);
239     /// @copydoc CNcbiError::SetFromErrno(void)
240     static void SetFromErrno(const string& extra);
241     /// @copydoc CNcbiError::SetFromErrno(void)
242     static void SetFromErrno(const char* extra);
243     /// @copydoc CNcbiError::SetFromErrno(void)
244     static void SetFromErrno(string&& extra);
245 
246 #if defined(NCBI_OS_MSWIN)
247     /// Set last error using Windows-specific error code
248     ///
249     /// @param native_err_code
250     ///   Windows-specific error code
251     /// @param extra
252     ///   Additional information
253     /// @note
254     ///   Not all Windows errors can be translated into ECode enum.
255     ///   In this case, Code() will return 'eUnknown'
256     static void SetWindowsError(int native_err_code);
257     /// @copydoc CNcbiError::SetWindowsError(int)
258     static void SetWindowsError(int native_err_code, const CTempString extra);
259     /// @copydoc CNcbiError::SetWindowsError(int)
260     static void SetWindowsError(int native_err_code, const string& extra);
261     /// @copydoc CNcbiError::SetWindowsError(int)
262     static void SetWindowsError(int native_err_code, const char* extra);
263     /// @copydoc CNcbiError::SetWindowsError(int)
264     static void SetWindowsError(int native_err_code, string&& extra);
265 
266     /// Set last error on MS Windows using GetLastError()
267     ///
268     /// @param extra
269     ///   Additional information
270     /// @note
271     ///   Not all Windows errors can be translated into ECode enum.
272     ///   In this case, Code() will return 'eUnknown'
273     static void SetFromWindowsError(void);
274     /// @copydoc CNcbiError::SetFromWindowsError(void)
275     static void SetFromWindowsError(const CTempString extra);
276     /// @copydoc CNcbiError::SetFromWindowsError(void)
277     static void SetFromWindowsError(const string& extra);
278     /// @copydoc CNcbiError::SetFromWindowsError(void)
279     static void SetFromWindowsError(const char* extra);
280     /// @copydoc CNcbiError::SetFromWindowsError(void)
281     static void SetFromWindowsError(string&& extra);
282 #endif  /* NCBI_OS_MSWIN */
283 
284 protected:
285     // Prohibit creation of 'empty' error object
286     CNcbiError(void);
287 
288 private:
289     static CNcbiError* x_Init(int err_code);
290     template<class Ty>
291     static CNcbiError* x_Init(int err_code, Ty extra);
292 #ifdef NCBI_OS_MSWIN
293     static void x_SetWindowsCodeCategory(CNcbiError* e);
294 #endif
295 
296 private:
297     mutable ECode m_Code;
298     ECategory     m_Category;
299     int           m_Native;
300     string        m_Extra;
301 };
302 
303 
304 /// Serialize error code + description provided by OS + extra string data
305 NCBI_XNCBI_EXPORT CNcbiOstream& operator<< (CNcbiOstream&     str,
306                                             const CNcbiError& err);
307 
308 
309 END_NCBI_SCOPE
310 
311 
312 /* @} */
313 
314 #endif  /* CORELIB___NCBIERROR__HPP */
315