4

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;

    ....
}

4 Answers 4

9

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
  • 2
    +1 for "if that's what's needed". If it bothers the OP to have so many parameters, he could make an object to carry that data, and just pass that object up that stack in the exception.
    – Mike
    Jul 24, 2014 at 14:11
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
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
  • -1 for "don't store this values inside the exception but just use them to create the exception message in the constructor." a string is good for textual output, but what about translation or checking out a specific value (e.g. an error code)? Are you then going to parse the string?
    – Andy
    Jul 24, 2014 at 20:56
  • In sorry, but I don't agree with you. The exceptions should be self explaining by their type. For instance, if during a login operation the program can't reach the server, it should throw a ServerNotFoundException, instead a generic LoginException with a specific error code. As msdn states here msdn.microsoft.com/en-us/library/seyhszts(v=vs.110).aspx the exceptions are a replacement error codes. So I don't think that encapsulate an identifier for the error is the right way to implement them. About the translations, you can easily use the Resource files, as the .Net Framework does.
    – simoneL
    Jul 25, 2014 at 0:05
  • you didn't say The exceptions should be self explaining by their type. I agree with that (although not completely). However... let's assume a timeout-exception, which should indicate the server to be reached, and the timeout-period. In your proposal you create a string with that values, and later you are not able to access them programmatically, only by parsing the string.
    – Andy
    Jul 25, 2014 at 7:11
  • Right, I didn't talk about the meaning of an exception. I showed some of the available options to avoid storing useless information into the exception. Also in your example I can't understand for what purpose you might be able to retrieve the connection configuration. The exception purpose is to stop the application flow, indicates the error typology by the exception type and give some additional details thorough the message.
    – simoneL
    Jul 25, 2014 at 11:18
  • There are some kinds of errors/exceptions I can react on by following an alternate route. In my example the caller may adjust the timeout by 10% and tries again. Or it tries another server instance. Or it wants to write to a database, that a specific server is not available.
    – Andy
    Jul 25, 2014 at 11:30
0

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
  • Never say never. Furthermore, exceptions are often used for error conditions you do expect to have to deal with, and often are. Even something as simple as opening a file is best handled via exceptions. Jul 24, 2014 at 23:51
  • @whatsisname fair enough - but those are exceptions to the rule (haha). I'm not necessarily convinced by the file-open case though, return null is better IMHO. Failing to write to an opened file, that is another matter.
    – gbjbaanb
    Jul 25, 2014 at 7:52
  • @gbjbaanb: Opening a file for reading is an example of an action for which both throw-on-error and return-error-code semantics should be available. If code is expecting "Try opening this file, and if that doesn't work try this other one" such a thing is better handled without exceptions. If a program will needs some data from a file in order to do anything useful, however, having the failed open request throw an exception will be much more useful than having it return null.
    – supercat
    Apr 21, 2015 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.