Almost all the exceptions I have ever written have been very lightweight, containing a String message and optionally a throwable. In some situations I have included some application specific enum or some other field.
public class MySpecialException()
{
private MyErrorCode errorCode;
public MySpecialException(String message, Throwable cause, MyErrorCode errorCode)
{
super(message, cause);
this.errorCode = errorCode;
}
....
}
Now I face a situation where I need to put in 5 or 6 fields in the exception because the error handler that catches them needs them to generate the output.
Would you consider that to be bad code? Can an exception be too big?
public class MySpecialException()
{
private String name;
private int age;
private int id;
private int height;
private String duck;
private String whatever;
....
}
Of course it can be too big – virtually everything about coding is a trade-off between different principles, and not wasting memory is one of them.
However, if you need the data in the exception to get the job done, then by definition it’s not too big. It would be too big only if there was another mechanism that achieves the same, leads to maintainable code and works like an exception.
But exceptions are first-class language elements that were invented specifically to achieve something that you can’t otherwise do (break control flow and transport data somewhere else in the call stack without having to change the intermediate callers), so I doubt that you could find another solution which fulfills that condition.
1
An exception can be too big, especially if you are going to serialize it and transfer over wire (to a remote client/server or a database for instance).
If it is on the same machine, and you are not pushing it, put those 5-10 values there. Or maybe it makes more sense to put them into their own class(es). Maybe you are not dealing with one exception here, but one exception carrying information about one person and one duck.
0
I think you don’t really need all that information. I suppose you need all these values to identify better the cause of failure, so you have different options to achieve this, or at least improve the current solution:
- Use a logger. You can log on a file or a database these values before throw the exception
- Just store the ID and retrieve manually the entity afterwards, if it’s stored in an accessible place like a database
- Pass to the exception only the values which are the cause of failures
Anyway, don’t store this values inside the exception but just use them to create the exception message in the constructor.
6
No, an exception cannot be too big (well, obviously it could but I’m assuming common sense here). What an exception can definitely be is far too much coupled to normal program logic.
Exceptions should never be used to pass information around in your program. they should be used solely for error conditions that you didn’t expect to ever have to deal with (again, common sense says this will include errors you did expect, but ones that do not occur very often at all).
So when you push all this information into an exception, ask what you’re going to do with it. If the exception is driver only from exceptional circumstances, then you generally want it to be as generic and simple as possible – its job is to tell you what went wrong, and possibly some more information that you could display to the user. Trying to use the information for any other purpose smells like you’re trying to use exceptions to manage cases.
Adding a exception handler that understand every exception you might throw means your handler becomes very much tied to your exception classes, and that means your handler cannot be in a self-contained library without referencing the application! When projects grow, you’ll find this becomes an annoying problem.
So, I wouldn’t. I’d stick to throwing exceptions as strings and codes. If you really must pass information about the error (eg which user was being processed) then keep an error (or transaction) log containing the data and use that after the exception is handled to manage the data – you can hopefully put the display generator in your application code, and have it kept separate from external systems.
3