Reputation: 279
I'm playing around with building a factory method for generating RuntimeExceptions.
The idea would be to throw an exception by performing the following snippet:
throw ExceptionFactory.build(CustomException.class, CustomException.NOT_FOUND);
The first parameter to the build method is the exception class, however the second parameter would reference an Enum that's defined within the CustomException class for loading up additional details when building the exception.
Example:
public class CustomException extends RuntimeException {
public static final ExceptionType NOT_FOUND = ExceptionType.NOT_FOUND;
//constructors, getters, setters, etc..
private enum ExceptionType {
NOT_FOUND(Status.NOT_FOUND, "These aren't the droids you're looking for!");
private Status status;
private String description;
private ExceptionType(Status status, String description){
this.status = status;
this.description = description;
}
//other methods here..
}
}
The question I have is with the ExceptionFactory.build(), how do I specify the parameters for the build() method such that the second parameter must be specific to the CustomException class?
If this approach sounds crazy, how could it be improved? The goal is to have a generic factory method for building exceptions that have details already pre loaded. What I want is to avoid is something like this..
ExceptionFactory.build(CustomException.class, "Some string...")
The idea is the description needs to be defined in the CustomException and not just anything when throwing the error. So how to enforce??
public class ExceptionFactory {
public static <T extends RuntimeException> T build(T e, ???){
//more logic here...
}
}
Upvotes: 3
Views: 327
Reputation: 180978
I'm not sure I actually see much value in what you propose to do. It's not clear to me how a complicated factory mechanism for generating exceptions improves on instantiating them directly where and when they are needed. Nevertheless, you can approach this issue by making your enums more functional.
For example,
public interface ExceptionEnum {
public Class<? extends RuntimeException> getExceptionClass();
}
public class CustomException extends RuntimeException {
enum Details implements ExceptionEnum {
GOOD, BAD, UGLY;
public Class<? extends RuntimeException> getExceptionClass() {
return CustomException.class;
}
};
// ...
}
// ...
throw ExceptionFactory.build(CustomException.GOOD);
ExceptionFactory.build()
need only require an argument of type ExceptionEnum
.
Upvotes: 1
Reputation: 198211
Instead of using an ExceptionFactory
something something, one way of implementing this would be to use factory methods in your exception types. For example:
public class CustomException extends RuntimeException {
private CustomException(String description) {...}
public static CustomException notFound() {
return new CustomException("not found");
}
....
}
This makes sure that any CustomException
users of your code get comes from one of your factory methods that populate the exception message with the information you chose. You can also add whatever arguments you want to the static factory methods, so different exception causes can require different parameters in the factory method.
Upvotes: 1
Reputation: 887767
You could use a marker interface:
interface ExceptionTypeEnum<T extends RuntimeException> {}
private enum ExceptionType implements ExceptionTypeEnum<CustomException> {
...
}
public static <T extends RuntimeException> T build(T e, ExceptionTypeEnum<T> type) {
Upvotes: 3