Sannu
Sannu

Reputation: 1276

Java language best solution for Exception implementation

I need to extend Exception class in my application and i ran into a situation.

My Parent Exception class with a httpCode setter/getter to translate the exception to http error code:

abstract class ParentException
{
    private int httpCode;

    protected ParentException()
    {
        this("");
    }

    public ParentException(String message)
    {
        super(message);
    }

    protected ParentException(Exception e)
    {
        super(e);
    }

    public int getHttpCode()
    {
        return httpCode;
    }

    public void setHttpCode(int httpCode)
    {
        this.httpCode = httpCode;
    }
}

Sub class: public class AccessDeniedException extends ParentException { public AccessDeniedException() { this(""); }

    public AccessDeniedException(String message)
    {
        super(message);
        setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
    }

    public AccessDeniedException(Exception e)
    {
        super(message);
        setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
    }
}

Similarly i have bunch of other exception implementations for various relevant http codes. What I do not like is that setHttpCode() method is in two places. I want this to be called just from one constructor.

I could have just one constructor in all classes as following (ofcourse I need to fix parent class similarly):

public class AccessDeniedException extends ParentException
{
    public AccessDeniedException()
    {
        this("");
    }

    public AccessDeniedException(String message)
    {
        this(message, null);
    }

    public AccessDeniedException(Exception e)
    {
        this("", e);
    }

    public AccessDeniedException(String message,Exception e)
    {
        super(message, e);
        setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
    }
}

But I am worried that if a constructor with just message or exception is called, root Exception or Throwable classes may not get instantiated properly. Do you see any issue with this approach? If not, what is the better way of doing this.

Upvotes: 1

Views: 82

Answers (2)

Joop Eggen
Joop Eggen

Reputation: 109547

One way would be to have in the base class:

protected abstract int getHttpCode();

And then every child class would need a:

@Override
protected getHttpCode() {
    return HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED;
}

Upvotes: 2

Sam
Sam

Reputation: 680

If you do it the second way you should probably pass in null as the message for the empty and Exception constructors.

The second approach will work OK, but you might see slightly different output compared to the first, as some Throwable constructors fill the detailMessage differently.

The same issue as described here was is seen in Exception's extension of Throwable. They solve it in the same way as your first example.

Of the two, I'd recommended using your first example as it follows the established convention and is more robust design if the superclass behavior changed.

Edit - M. Prokhorov noted that there should be an abstract getter method, this approach would work and is better design. Further along those lines I would suggest including the httpCode as part of the constructors of Parent.

e.g.

protected ParentException(int httpCode)
{
    super();
    this.httpCode = httpCode;
}

public AccessDeniedException()
{
    super(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
}

You could also extract the code to a constant (static final) variable.

Upvotes: 1

Related Questions