Project

General

Profile

Statistics
| Branch: | Revision:

root / include / cexception.h @ fbe00e73

History | View | Annotate | Download (11.7 KB)

1
//==========================================================================
2
//  CEXCEPTION.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Exception class
8
//
9
//==========================================================================
10

    
11
/*--------------------------------------------------------------*
12
  Copyright (C) 1992-2008 Andras Varga
13
  Copyright (C) 2006-2008 OpenSim Ltd.
14

15
  This file is distributed WITHOUT ANY WARRANTY. See the file
16
  `license' for details on this and other legal matters.
17
*--------------------------------------------------------------*/
18

    
19
#ifndef __CEXCEPTION_H
20
#define __CEXCEPTION_H
21

    
22
#include <stdarg.h>
23
#include <exception>
24
#include <stdexcept>
25
#include "simkerneldefs.h"
26
#include "simtime_t.h"
27
#include "errmsg.h"
28
#include "opp_string.h"
29

    
30
NAMESPACE_BEGIN
31

    
32
class cObject;
33
class cComponent;
34

    
35
/**
36
 * Exception class.
37
 *
38
 * @ingroup SimSupport
39
 */
40
class SIM_API cException : public std::exception
41
{
42
  protected:
43
    int errorcode;
44
    std::string msg;
45

    
46
    int simulationstage;
47
    eventnumber_t eventnumber;
48
    simtime_t simtime;
49

    
50
    bool hascontext;
51
    std::string contextclassname;
52
    std::string contextfullpath;
53
    int moduleid;
54

    
55
    /**
56
     * Helper function for constructors: assembles and stores the message text.
57
     * If the first arg is non-NULL, the message text will be prepended (if needed)
58
     * with the object type and name, like this: "(cArray)array: ..."
59
     */
60
    void init(const cObject *obj, OppErrorCode errorcode, const char *fmt, va_list va);
61

    
62
    // helper for init()
63
    void storeCtx();
64

    
65
    // default constructor, for subclasses only.
66
    cException();
67

    
68
    //
69
    // Helper, called from cException constructors.
70
    //
71
    // If an exception occurs in initialization code (during construction of
72
    // global objects, before main() is called), there is nobody who could
73
    // catch the error, so it would just cause a program abort.
74
    // Here we handle this case manually: if cException ctor is invoked before
75
    // main() has started, we print the error message and call exit(1).
76
    //
77
    void exitIfStartupError();
78

    
79
  public:
80
    /** @name Constructors, destructor */
81
    //@{
82
    /**
83
     * Error is identified by an error code, and the message comes from a
84
     * string table. The error string may expect printf-like arguments
85
     * (%s, %d) which also have to be passed to the constructor.
86
     */
87
    cException(OppErrorCode errcode,...);
88

    
89
    /**
90
     * To be called like printf(). The error code is set to eCUSTOM.
91
     */
92
    cException(const char *msg,...);
93

    
94
    /**
95
     * Error is identified by an error code, and the message comes from a
96
     * string table. The error string may expect printf-like arguments
97
     * (%s, %d) which also have to be passed to the constructor.
98
     * The 1st arg is the object where the error occurred: its class and
99
     * object name will be prepended to the message like this: "(cArray)arr".
100
     */
101
    cException(const cObject *where, OppErrorCode errcode,...);
102

    
103
    /**
104
     * To be called like printf(). The error code is set to eCUSTOM.
105
     * The 1st arg is the object where the error occurred: its class and
106
     * object name will be prepended to the message like this: "(cArray)arr".
107
     */
108
    cException(const cObject *where, const char *msg,...);
109

    
110
    /**
111
     * We unfortunately need to copy exception objects when handing them back
112
     * from an activity().
113
     */
114
    cException(const cException&);
115

    
116
    /**
117
     * Virtual copy constructor. We unfortunately need to copy exception objects
118
     * when handing them back from an activity().
119
     */
120
    virtual cException *dup() const {return new cException(*this);}
121

    
122
    /**
123
     * Destructor.
124
     */
125
    virtual ~cException() throw() {}
126
    //@}
127

    
128
    /** @name Updating the exception message */
129
    //@{
130
    /**
131
     * Overwrites the message text with the given one.
132
     */
133
    virtual void setMessage(const char *txt) {msg = txt;}
134

    
135
    /**
136
     * Prefixes the message with the given text and a colon.
137
     */
138
    virtual void prependMessage(const char *txt) {msg = std::string(txt) + ": " + msg;}
139
    //@}
140

    
141
    /** @name Getting exception info */
142
    //@{
143
    /**
144
     * Whether the exception represents an error or a normal (non-error)
145
     * terminating condition (e.g. "Simulation completed").
146
     */
147
    virtual bool isError() const {return true;}
148

    
149
    /**
150
     * Returns the error code.
151
     */
152
    virtual int getErrorCode() const {return errorcode;}
153

    
154
    /**
155
     * Returns the text of the error. Redefined from std::exception.
156
     */
157
    virtual const char *what() const throw() {return msg.c_str();}
158

    
159
    /**
160
     * Returns a formatted message that includes the "Error" word, context
161
     * information, the event number and simulation time if available
162
     * and relevant, in addition to the exception message (what()).
163
     */
164
    virtual std::string getFormattedMessage() const;
165

    
166
    /**
167
     * Returns in which stage of the simulation the exception object was created:
168
     * during network building (CTX_BUILD), network initialization (CTX_INITIALIZE),
169
     * simulation execution (CTX_EVENT), finalization (CTX_FINISH), or network
170
     * cleanup (CTX_CLEANUP).
171
     */
172
    virtual int getSimulationStage() const {return simulationstage;}
173

    
174
    /**
175
     * Returns the event number at the creation of the exception object.
176
     */
177
    virtual eventnumber_t getEventNumber() const {return eventnumber;}
178

    
179
    /**
180
     * Returns the simulation time at the creation of the exception object.
181
     */
182
    virtual simtime_t getSimtime() const {return simtime;}
183

    
184
    /**
185
     * Returns true if the exception has "context info", that is, it occurred
186
     * within a known module or channel. getContextClassName(), getContextFullPath()
187
     * and getModuleID() may only be called if this method returns true.
188
     */
189
    virtual bool hasContext() const {return hascontext;}
190

    
191
    /**
192
     * Returns the class name (NED type name) of the context where the
193
     * exception occurred.
194
     */
195
    virtual const char *getContextClassName() const {return contextclassname.c_str();}
196

    
197
    /**
198
     * Returns the full path of the context where the exception
199
     * occurred.
200
     */
201
    virtual const char *getContextFullPath() const {return contextfullpath.c_str();}
202

    
203
    /**
204
     * Returns the ID of the module where the exception occurred,
205
     * or -1 if it was not inside a module. The module may not exist
206
     * any more when the exception is caught (ie. if the exception occurs
207
     * during network setup, the network is cleaned up immediately).
208
     */
209
    virtual int getModuleID() const {return moduleid;}
210
    //@}
211
};
212

    
213
/**
214
 * Thrown when the simulation is completed.
215
 * For example, cSimpleModule::endSimulation() throws this exception.
216
 * Statistics object may also throw this exception to
217
 * signal that accuracy of simulation results has reached the desired level.
218
 *
219
 * @ingroup Internals
220
 */
221
class SIM_API cTerminationException : public cException
222
{
223
  public:
224
    /**
225
     * Error is identified by an error code, and the message comes from a
226
     * string table. The error string may expect printf-like arguments
227
     * (%s, %d) which also have to be passed to the constructor.
228
     */
229
    cTerminationException(OppErrorCode errcode,...);
230

    
231
    /**
232
     * To be called like printf(). The error code is set to eCUSTOM.
233
     */
234
    cTerminationException(const char *msg,...);
235

    
236
    /**
237
     * We unfortunately need to copy exception objects when handing them back
238
     * from an activity().
239
     */
240
    cTerminationException(const cTerminationException& e) : cException(e) {}
241

    
242
    /**
243
     * Virtual copy constructor. We unfortunately need to copy exception objects
244
     * when handing them back from an activity().
245
     */
246
    virtual cTerminationException *dup() const {return new cTerminationException(*this);}
247

    
248
    /**
249
     * Termination exceptions are generally not errors, but messages like
250
     * "Simulation completed".
251
     */
252
    virtual bool isError() const {return false;}
253
};
254

    
255
/**
256
 * Thrown when the simulation kernel or other components detect a runtime
257
 * error. For example, cSimpleModule::scheduleAt() throws this exception when
258
 * the specified simulation time is in the past, or the message pointer
259
 * is NULL.
260
 *
261
 * @ingroup Internals
262
 */
263
class SIM_API cRuntimeError : public cException
264
{
265
  protected:
266
    // internal
267
    void breakIntoDebuggerIfRequested();
268

    
269
  public:
270
    /**
271
     * Error is identified by an error code, and the message comes from a
272
     * string table. The error string may expect printf-like arguments
273
     * (%s, %d) which also have to be passed to the constructor.
274
     */
275
    cRuntimeError(OppErrorCode errcode,...);
276

    
277
    /**
278
     * To be called like printf(). The error code is set to eCUSTOM.
279
     */
280
    cRuntimeError(const char *msg,...);
281

    
282
    /**
283
     * Error is identified by an error code, and the message comes from a
284
     * string table. The error string may expect printf-like arguments
285
     * (%s, %d) which also have to be passed to the constructor.
286
     * The 1st arg is the object where the error occurred: its class and
287
     * object name will be prepended to the message like this: "(cArray)arr".
288
     */
289
    cRuntimeError(const cObject *where, OppErrorCode errcode,...);
290

    
291
    /**
292
     * To be called like printf(). The error code is set to eCUSTOM.
293
     * The 1st arg is the object where the error occurred: its class and
294
     * object name will be prepended to the message like this: "(cArray)arr".
295
     */
296
    cRuntimeError(const cObject *where, const char *msg,...);
297

    
298
    /**
299
     * We unfortunately need to copy exception objects when handing them back
300
     * from an activity().
301
     */
302
    cRuntimeError(const cRuntimeError& e) : cException(e) {}
303

    
304
    /**
305
     * Virtual copy constructor. We unfortunately need to copy exception objects
306
     * when handing them back from an activity().
307
     */
308
    virtual cRuntimeError *dup() const {return new cRuntimeError(*this);}
309
};
310

    
311
/**
312
 * This exception is only thrown from cSimpleModule::deleteModule()
313
 * if the current module is to be deleted, in order to exit that module
314
 * immediately.
315
 *
316
 * @ingroup Internals
317
 */
318
class SIM_API cDeleteModuleException : public cException
319
{
320
  public:
321
    /**
322
     * Default ctor.
323
     */
324
    cDeleteModuleException() : cException() {}
325

    
326
    /**
327
     * We unfortunately need to copy exception objects when handing them back
328
     * from an activity().
329
     */
330
    cDeleteModuleException(const cDeleteModuleException& e) : cException(e) {}
331

    
332
    /**
333
     * Virtual copy constructor. We unfortunately need to copy exception objects
334
     * when handing them back from an activity().
335
     */
336
    virtual cDeleteModuleException *dup() const {return new cDeleteModuleException(*this);}
337

    
338
    /**
339
     * This exception type does not represent an error condition.
340
     */
341
    virtual bool isError() const {return false;}
342
};
343

    
344
/**
345
 * Used internally when deleting an activity() simple module.
346
 * Then, the coroutine running activity() is "asked" to throw a
347
 * cStackCleanupException to achieve stack unwinding, a side effect of
348
 * exceptions, in order to properly clean up activity()'s local variables.
349
 *
350
 * @ingroup Internals
351
 */
352
class SIM_API cStackCleanupException : public cException
353
{
354
  public:
355
    /**
356
     * Default ctor.
357
     */
358
    cStackCleanupException() : cException() {}
359

    
360
    /**
361
     * We unfortunately need to copy exception objects when handing them back
362
     * from an activity().
363
     */
364
    cStackCleanupException(const cStackCleanupException& e) : cException(e) {}
365

    
366
    /**
367
     * Virtual copy constructor. We unfortunately need to copy exception objects
368
     * when handing them back from an activity().
369
     */
370
    virtual cStackCleanupException *dup() const {return new cStackCleanupException(*this);}
371

    
372
    /**
373
     * This exception type does not represent an error condition.
374
     */
375
    virtual bool isError() const {return false;}
376
};
377

    
378
NAMESPACE_END
379

    
380

    
381
#endif
382

    
383