summaryrefslogtreecommitdiff
path: root/cpp/include/IceUtil/Exception.h
blob: 249dd05701e3711893291337164cee0ac40d948d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//

#ifndef ICE_UTIL_EXCEPTION_H
#define ICE_UTIL_EXCEPTION_H

#include <IceUtil/Config.h>

#include <exception>
#include <vector>

namespace IceUtil
{

/**
 * Abstract base class for all Ice exceptions. Use the Ice::Exception alias instead
 * of IceUtil::Exception.
 * \headerfile Ice/Ice.h
 */
class ICE_API Exception : public std::exception
{
public:

    /**
     * Constructs the exception. Equivalent to Exception(nullptr, 0).
     */
    Exception();

    /**
     * Constructs the exception.
     * @param file The file where this exception is constructed.
     * @param line The line where this exception is constructed.
     */
    Exception(const char* file, int line);

#ifndef ICE_CPP11_COMPILER
    virtual ~Exception() throw() = 0;
#endif

    /**
     * Returns the type ID of this exception. This corresponds to the Slice
     * type ID for Slice-defined exceptions, and to a similar fully scoped name
     * for other exceptions. For example "::IceUtil::SyscallException".
     * @return The type ID of this exception
     */
    virtual std::string ice_id() const = 0;

    /**
     * Outputs a description of this exception to a stream.
     * @param os The output stream.
     */
    virtual void ice_print(std::ostream& os) const;

    /**
     * Returns a description of this exception.
     * @return The description.
     */
    virtual const char* what() const ICE_NOEXCEPT;
#ifdef ICE_CPP11_MAPPING

    /**
     * Returns a shallow polymorphic copy of this exception.
     * @return A unique_ptr to the new shallow copy.
     */
    std::unique_ptr<Exception> ice_clone() const;
#else
    /**
     * Returns a shallow polymorphic copy of this exception.
     * @return A pointer to the new shallow copy. The caller owns the returned object.
     */
    virtual Exception* ice_clone() const = 0;

    ICE_DEPRECATED_API("ice_name() is deprecated, use ice_id() instead.")
    std::string ice_name() const;
#endif

    /**
     * Throws this exception.
     */
    virtual void ice_throw() const = 0;

    /**
     * Returns the name of the file where this exception was constructed.
     * @return The file name.
     */
    const char* ice_file() const;

    /**
     * Returns the line number where this exception was constructed.
     * @return The line number.
     */
    int ice_line() const;

    /**
     * Returns the stack trace at the point this exception was constructed
     * @return The stack trace as a string.
     */
    std::string ice_stackTrace() const;

protected:

#ifdef ICE_CPP11_MAPPING
    /// \cond INTERNAL
    virtual Exception* ice_cloneImpl() const = 0;
    /// \endcond
#endif

private:

    const char* _file;
    int _line;
    const std::vector<void*> _stackFrames;
    mutable ::std::string _str; // Initialized lazily in what().
};

ICE_API std::ostream& operator<<(std::ostream&, const Exception&);

#ifdef ICE_CPP11_MAPPING

/**
 * Helper template for the implementation of Ice::Exception.
 * It implements ice_clone and ice_throw.
 * \headerfile Ice/Ice.h
 */
template<typename E, typename B = Exception>
class ExceptionHelper : public B
{
public:

    using B::B;

    std::unique_ptr<E> ice_clone() const
    {
        return std::unique_ptr<E>(static_cast<E*>(ice_cloneImpl()));
    }

    virtual void ice_throw() const override
    {
        throw static_cast<const E&>(*this);
    }

protected:

    /// \cond INTERNAL
    virtual Exception* ice_cloneImpl() const override
    {
        return new E(static_cast<const E&>(*this));
    }
    /// \endcond
};

#else // C++98 mapping

/**
 * Helper template for the implementation of Ice::Exception. It implements ice_throw.
 * \headerfile Ice/Ice.h
 */
template<typename E>
class ExceptionHelper : public Exception
{
public:

    ExceptionHelper()
    {
    }

    ExceptionHelper(const char* file, int line) : Exception(file, line)
    {
    }

    virtual void ice_throw() const
    {
        throw static_cast<const E&>(*this);
    }
};

#endif

/**
 * This exception indicates an attempt to dereference a null IceUtil::Handle or
 * IceInternal::Handle.
 * \headerfile Ice/Ice.h
 */
class ICE_API NullHandleException : public ExceptionHelper<NullHandleException>
{
public:

    NullHandleException(const char*, int);
    virtual std::string ice_id() const;

#ifndef ICE_CPP11_MAPPING
    virtual NullHandleException* ice_clone() const;
#endif
};

/**
 * This exception indicates that a function was called with an illegal parameter
 * value. It is used only by the Slice to C++98 mapping; std::invalid_argument is
 * used by the Slice to C++11 mapping.
 * \headerfile Ice/Ice.h
 */
class ICE_API IllegalArgumentException : public ExceptionHelper<IllegalArgumentException>
{
public:

    IllegalArgumentException(const char*, int);
    IllegalArgumentException(const char*, int, const std::string&);

#ifndef ICE_CPP11_COMPILER
    virtual ~IllegalArgumentException() throw();
#endif

    virtual std::string ice_id() const;
    virtual void ice_print(std::ostream&) const;

#ifndef ICE_CPP11_MAPPING
    virtual IllegalArgumentException* ice_clone() const;
#endif

    /**
     * Provides the reason this exception was thrown.
     * @return The reason.
     */
    std::string reason() const;

private:

    const std::string _reason;
};

/**
 * This exception indicates the failure of a string conversion.
 * \headerfile Ice/Ice.h
 */
class ICE_API IllegalConversionException : public ExceptionHelper<IllegalConversionException>
{
public:

    IllegalConversionException(const char*, int);
    IllegalConversionException(const char*, int, const std::string&);

#ifndef ICE_CPP11_COMPILER
    virtual ~IllegalConversionException() throw();
#endif

    virtual std::string ice_id() const;
    virtual void ice_print(std::ostream&) const;

#ifndef ICE_CPP11_MAPPING
    virtual IllegalConversionException* ice_clone() const;
#endif

    /**
     * Provides the reason this exception was thrown.
     * @return The reason.
     */
    std::string reason() const;

private:

    const std::string _reason;
};

/**
 * This exception indicates the failure of a system call.
 * \headerfile Ice/Ice.h
 */
class ICE_API SyscallException : public ExceptionHelper<SyscallException>
{
public:

    SyscallException(const char*, int, int);

#ifndef ICE_CPP11_COMPILER
    virtual ~SyscallException() throw();
#endif

    virtual std::string ice_id() const;
    virtual void ice_print(std::ostream&) const;

#ifndef ICE_CPP11_MAPPING
    virtual SyscallException* ice_clone() const;
#endif

    /**
     * Provides the error number returned by the system call.
     * @return The error number.
     */
    int error() const;

private:

    const int _error;
};

#ifdef ICE_CPP11_MAPPING

template<typename E>
using SyscallExceptionHelper = ExceptionHelper<E, SyscallException>;

#else // C++98 mapping

/**
* Helper template for the implementation of SyscallException. It implements
* ice_throw.
* \headerfile Ice/Ice.h
*/
template<typename E>
class SyscallExceptionHelper : public SyscallException
{
public:

    SyscallExceptionHelper(const char* file, int line, int errorCode) :
        SyscallException(file, line, errorCode)
    {
    }

    virtual void ice_throw() const
    {
        throw static_cast<const E&>(*this);
    }
};

#endif

/**
 * This exception indicates the failure to lock a file.
 * \headerfile Ice/Ice.h
 */
class ICE_API FileLockException : public ExceptionHelper<FileLockException>
{
public:

    FileLockException(const char*, int, int, const std::string&);

#ifndef ICE_CPP11_COMPILER
    virtual ~FileLockException() throw();
#endif

    virtual std::string ice_id() const;
    virtual void ice_print(std::ostream&) const;

#ifndef ICE_CPP11_MAPPING
    virtual FileLockException* ice_clone() const;
#endif

    /**
     * Returns the path to the file.
     * @return The file path.
     */
    std::string path() const;

    /**
     * Returns the error number for the failed locking attempt.
     * @return The error number.
     */
    int error() const;

private:

    const int _error;
    std::string _path;
};

/**
 * This exception indicates an IceUtil::Optional is not set.
 * Used only by the Slice to C++98 mapping.
 * \headerfile Ice/Ice.h
 */
class ICE_API OptionalNotSetException : public ExceptionHelper<OptionalNotSetException>
{
public:

    OptionalNotSetException(const char*, int);
    virtual std::string ice_id() const;

#ifndef ICE_CPP11_MAPPING
    virtual OptionalNotSetException* ice_clone() const;
#endif
};

}

namespace IceUtilInternal
{

enum StackTraceImpl { STNone, STDbghelp, STLibbacktrace, STLibbacktracePlus, STBacktrace };

ICE_API StackTraceImpl stackTraceImpl();

}

#endif