3

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...
  }

}
7
  • Is it that you have several different custom exception types, each of which have this sort of enum thing? I don't think that's likely to get anywhere. You might be able to use a builder-like syntax, though, instead of an enum? Commented Sep 2, 2015 at 19:54
  • 1
    @byte-crunch, the language of Java type parameters does not have any means to describe a type in terms of its containing type. SLaks's idea could work, but I don't think that, or your starting idea, actually take you anywhere you actually want to be. Commented Sep 2, 2015 at 19:59
  • 3
    you can probably simplify the design, eventually to something like throw FooException.NOT_FOUND.build(). the enum contains all info necessary to build the exception. or just throw FooException.notFound() Commented Sep 2, 2015 at 20:01
  • 1
    @bayou.io, that's a good point, I think your suggestion is a cleaner approach.. Commented Sep 2, 2015 at 20:11
  • 1
    If you know the class you want to instantiate, and also know the appropriate parameters to pass to it, I don't see how throw ExceptionFactory.build(FooException.class, FooException.NOT_FOUND) is an improvement over just throw new FooException(FooException.NOT_FOUND) Commented Sep 2, 2015 at 20:24

3 Answers 3

3

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) {
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

1

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.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.