简体   繁体   中英

How I can get a list of all possible exceptions of function

How I can scan my code and get all possible throws MyException errorCode's of execute() function?

Errors const:

public enum ErrorId {
  OK(1),
  REPORT_LIMIT(2),
  NOT_UNIQUE_FIELD(3),
  INCORRECT_PROPERTY(4);
  private int id;

  ErrorId(int id) {
     this.id = id;     
  }
}

For example I have 'MyException' :

public class MyException extends Exception {    
  @Getter 
  protected final ErrorId errorCode;

  public MyException(ErrorId errorCode) {
       this.errorCode = errorCode;        
  } 
}

And class with method:

public class MyClass {

public void execute() throws MyException {
    //do something 1
    ...
    if(isSomethingWrong1) throw new MyException(ErrorId.REPORT_LIMIT);

    executeMethod2();

    //do something N
    if(isSomethingWrongN) throw new MyException(ErrorId....);
}

public void executeMethod2() throws MyException  {
//  ...
    throw new MyException(ErrorId....)
//  ...
}
}

I don't think there's an answer here that you'll like.

Reflection won't work in this case, because it's concerned with types, not values. The compiler can't help you here, either, because if the error code comes in through a variable, then at runtime, all bets are off -- the value could be any possible value of the type you're using. If you're using an enum for the code value, then you have a known list of all possible values, but you won't know which ones are actually used in any particular function without reading that function. A static analysis tool may be of use here, but you'd need to continue running it over time to keep this information up to date.

However, all is not lost. As I said in my second comment, you have another choice -- extract subclasses. Let's consider this definition of your Exception class.

public abstract class MyException extends Exception {    
    @Getter 
    protected final ErrorId errorCode;

    public MyException(ErrorId errorCode) {
        this.errorCode = errorCode;        
    } 
}

It's the same as yours is now, but it's abstract . This class is open for extension. So we could create a subclass ReportLimitException like this:

public class ReportLimitException extends MyException {
    public ReportLimitException() {
        super(ErrorId.REPORT_LIMIT);
    }
}

and another like this, for example:

public class DuplicateFieldException extends MyException {
    public DuplicateFieldException() {
        super(ErrorId.NOT_UNIQUE_FIELD);
    }
}

Now, any given method can advertise which particular exceptions it uses via its throws clause. This is, in fact, why that clause exists.

public void execute() throws ReportLimitException, DuplicateFieldException {
    //do something 1
    //...
    if(isSomethingWrong1) throw new ReportLimitException();

    executeMethod2();

    //do something N
    if(isSomethingWrongN) throw new DuplicateFieldException();
}

At this point, if you advertise the exceptions explicitly, you'll have achieved your goal, at the cost of some potentially long throws clauses (which should actually be a hint to you that the method may be doing too much work anyway). Alternatively if you don't want to advertise every exception like that, you could also use your IDE's "find references" feature to locate every place where those exceptions are created (look for references to the constructors).

And the calling code doesn't even have to be aware of the change. It can continue using code like this:

try {
    // stuff that might throw any of your exceptions
} catch (MyException ex) {
    switch (ex.getErrorCode()) {
        // handle the cases...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM