Reputation: 1276
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
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
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