Please do not write error handling code within your files. I am currently working on a include file that should handle most of our errors, it shoudl be as easy to use as...
guard( blah );
code
unguard();
with various macros to also enable you to handle exceptions yourself. I would also like to do away with the 'console' window and rather log these directly to a file, and dump output from debugging directly to the window. I see no real need to have this console window open really, unless others object.
++cire.
Error handler
Draft error handling, comments welcome
I hope this makes since now.
In its simplest terms it allows something like...
It also provides mechanics for you to handle errors itself, it will track itself nest deep (or at least it will once i add the global debugger object) and enable us to completely track the state of how the error was invoked and what path it followed to get to it.
++Cire.
Code: Select all
/*
** File: TA3D_Exception.h
** Notes:
** Cire: This file should be used to handle errors. It is rather simple to use and
** provides methods for tossing an exception and figuring out where it came
** from, as well as who it went through.
** To guard a block of code, with the error to be caught by anybody higher-up:
** guard (Action);
** ...
** unguard;
** If something happens between the guard and unguard, someone will eventually
** catch it and display an error, or act on it.
**
** To catch errors from lower blocks of code, do as above but put catches in
** for uchar*, cException*, and any other types (including ...) that you
** need.
*/
#pragma once
namespace TA3D
{
namespace EXCEPTION
{
// prototypes: internal use only.
extern void IncrementIndent(void);
extern void DecrementIndent(void);
extern uint32 GetIndentLevel(void);
// Use this to throw a nice, more useful debugging string
// Be sure to SetExceptionStatus (false) if you handle an exception.
// Don't worry about manually setting it to true though.
extern void __cdecl ThrowFatal( const char *Format, ... );
extern bool IsExceptionInProgress (void);
extern void SetExceptionStatus (bool E);
#ifdef DEBUG
extern void __cdecl GlobalDebuggerPrintf( const char *Format, ... );
#define dprintf GlobalDebuggerPrintf
#else
#define dprintf //
#endif
// In debug builds, let unhandled errors (referencing bad pointer, etc.) crash
// and give us debugger control. Otherwise, for release builds, give us a
// stack trace. This is used in the unguard macro below.
#ifdef DEBUG
#define UNKNOWN_ERROR_CATCH
#else
#define UNKNOWN_ERROR_CATCH \
catch (...) \
{ \
DecrementIndent (); \
dprintf ("Tossing Unhandled Exception (%s)\n", __GUARD__BLOCK__NAME__); \
SetExceptionStatus (true); \
throw (new cException (__GUARD__BLOCK__NAME__, "Unhandled Exception"));\
}
#endif
// Used for both debug and release builds
#define guard(name) \
{ \
static char *__GUARD__BLOCK__NAME__ = #name; \
dprintf ("Guard: %s\n", __GUARD__BLOCK__NAME__); \
IncrementIndent (); \
try \
{
// Don't need to use this if using unguard. Use this if using
// guardcatch, et. al.
#define guardend \
DecrementIndent (); \
dprintf ("Unguard: %s\n", __GUARD__BLOCK__NAME__); \
}
#define unguard \
} \
catch (cException *E) \
{ \
E->AddTosser (__GUARD__BLOCK__NAME__); \
DecrementIndent (); \
dprintf ("Tossing exception higher (%s)\n", __GUARD__BLOCK__NAME__); \
SetExceptionStatus (true); \
throw (E); \
} \
catch (string ErrorName) \
{ \
DecrementIndent (); \
dprintf ("Tossing string higher as exception (%s)\n", __GUARD__BLOCK__NAME__); \
SetExceptionStatus (true); \
throw (new cException (__GUARD__BLOCK__NAME__, ErrorName)); \
} \
UNKNOWN_ERROR_CATCH \
guardend;
// Use if you want to handle ExceptionD yourself
#define guardcatch(varname) \
} \
catch (cException *varname) \
#ifdef TA3D_SUPERGUARD
#define sguard(a) guard(a)
#define sunguard unguard
#else
#define sguard(a)
#define sunguard
#endif
// Convenience macro
#define SAFETRY(cmd) { guard (cmd); cmd; unguard; }
// Will eat any exceptions caused by a piece of code
#define IMPUNITY(cmd) { try { cmd; } catch (...) { } }
// Disable exception handling and save executable size (and speed?)
#ifdef TA3D_NOGUARD
#undef guard
#define guard(x)
#undef unguard
#define unguard
#undef guardend
#define guardend
#undef guardcatch
#define guardcatch(varname) cException *varname = NULL; if (false)
#endif // TA3D_NOGUARD
// The actual exception class
class cException
{
public:
cException( const String _Instigator, const String _ErrorName )
{
Instigator = _Instigator;
ErrorName = _ErrorName;
TossList = "";
return;
}
void AddTosser( const String Tosser )
{
TossList += " <Tosser>DebugPrintf (Buffer);
return;
}
} // namespace EXCEPTION
} // namespace TA3D
In its simplest terms it allows something like...
Code: Select all
guard (Detecting system information);
InitSystemInfo ();
unguard;
++Cire.
- zuzuf
- Administrateur - Site Admin
- Posts: 3281
- Joined: Mon Oct 30, 2006 8:49 pm
- Location: Toulouse, France
- Contact:
Well, the Console object already output everything to a file, but I see no reason to remove the console window, since it's were you can type commands, to spawn units for example...
Your error handling code is great, and for those who don't want to use it they can still debug the old way. We really need an error handler, the code is becoming huge and hard to debug.
As far as the submitting code is concerned, I don't know why it's doing this since it's a forum I installed in the sourceforge web space. But I will try to fix this.
Your error handling code is great, and for those who don't want to use it they can still debug the old way. We really need an error handler, the code is becoming huge and hard to debug.
As far as the submitting code is concerned, I don't know why it's doing this since it's a forum I installed in the sourceforge web space. But I will try to fix this.
=>;-D Penguin Powered
Who is online
Users browsing this forum: No registered users and 47 guests