0

I've ErrorFactory class which based on error code creates an instance of different type of Errors. Also I have Output class which might contains one of those error types.

Code below shows how I am trying to use it, but unfortunately getting error. Could you please help me figure out what is wrong there and suggest better design. Thanks for any help!

OutputLike output = new OutputLike();
ErrorFactory errorFactory = new ErrorFactory();
int errorCode = ((Long)error.get("error_code")).intValue();
output.setError(errorFactory.<Error>getError(errorCode, error));


Error:(97, 27) java: method setError in class com.electronsoftware.VKLiker.responseoutput.output.Output<T> cannot be applied to given types;
  required: com.electronsoftware.VKLiker.error.Error
  found: java.lang.Object
  reason: actual argument java.lang.Object cannot be converted to com.electronsoftware.VKLiker.error.Error by method invocation conversion

======

public class ErrorFactory <T extends Error> {
    public <T> T getError(int error_code, JSONObject errorBody){
        Error.ErrorType errorType = Error.ErrorType.values()[error_code];

        switch(errorType){
            case CAPTCHA_NEEDED:{
                return (T) Parser.parseCaptchaRequiredError(errorBody);
            }
            case USER_AUTHORIZATION_FAILED:{
                break;
            }
            case TOO_MANY_REQUESTS:{
                break;
            }
            case NOT_ENOUGH_PERMISSIONS:{
                break;
            }
            case UNKNOWN:{
                break;
            }
        }
        return null;
    }
}

====

public class OutputLike <E extends Error> extends Output <E> {
    ....
}

public abstract class Output <T extends Error> {

    private boolean isError;
    private T error;

    public boolean isError(){
        return this.isError;
    }
    public T getError(){
        return this.error;
    }
    public void setError(T error){
        this.error = error;
    }
}

====

public static ErrorCaptchaRequired parseCaptchaRequiredError(JSONObject error){

    ErrorCaptchaRequired captchaError = null;
    ....
    captchaError = new ErrorCaptchaRequired(msg, captchaId, captchaUrl);
    return captchaError;
}

====

public class ErrorCaptchaRequired extends Error {
........
}
7
  • 2
    You should consider renaming these classes, Errors are serious problems that can result in an unstable JVM, such as an OutOfMemoryError. These should be Exceptions, not Errors. Developers should never catch Errors unless there is a fantastically good reason for doing so. Commented Oct 14, 2014 at 20:59
  • 1
    The error is in the beginning of his post. Commented Oct 14, 2014 at 21:00
  • 1
    @Wrench So it does, I'd missed it Commented Oct 14, 2014 at 21:02
  • just cast agrument: output.setError((Error)errorFactory.<Error>getError(errorCode, error)); Commented Oct 14, 2014 at 21:04
  • 1
    I don't think you need generics here. getError should just return Error. You should also heed the advice given by @JonK about Error vs. Exception. Commented Oct 14, 2014 at 21:19

3 Answers 3

3

Two problems:

A) You are using a raw (untyped) ErrorFactory, which strips all generic info from the instance. Change to:

ErrorFactory<Error> errorFactory = new ErrorFactory<Error>();

B) Even if you fix A), you have typed getError() with <T> that is hiding the type T of the class.
Change

public <T> T getError(int error_code, JSONObject errorBody){

To

public T getError(int error_code, JSONObject errorBody){

Unless you really need to type the factory, I would make it untyped and simply return Error.

Also, naming any class the same as a java.lang class is a bad idea. Call it Problem or something.

Sign up to request clarification or add additional context in comments.

Comments

2

ErrorFactory errorFactory = new ErrorFactory(); instantiates ErrorFactory with the default type, Object. You need to tell what type ErrorFactory should hold, when declaring it.

ErrorFactory<CLASSNAME> errorFactory = new ...

6 Comments

Thing is at the declaration of ErrorFactory I don't know exactly what type of error it is. Idea of error factory is to construct me required error object by passing just error_code. So given error_code it constructs me and return different type of errors.
so I don't see other solution than casting on base type
You have control over all classes? Might be time to refactor some.
This answer is on the right track for explaining the compilation error. In fact, using a raw ErrorFactory causes all methods to be erased as well. This causes getError to return raw Object despite the witness. (A witness is e.g. <Error> in errorFactory.<Error>getError(errorCode, error).)
I do have access to all classes, do you have any suggestions how I can improve design by refactoring current model?
|
2

So based on

and suggest

if you want to consider another approach (tested and working), here is abstract solution. We have base

public class ValidationError{    
   public boolean isExpected() {
     return expected;
   }
}

to contain Error representation and attributes. Also

public class ScenarioError{
    public String getMessage() {
        return message;
    }

}

for test scenarios related errors, so we keep tracking them. Next is

public class ValidationErrorBuilder{
    public List<ValidationError> getValidationErrors(...){
    }
}

to construct found errors. And

public class ScenarioErrorsContainer{
   public String getErrorMessage() {
   }
}

to keep and get for processing already found errors.

Of course you'll have to add some required/needed interfaces (based on your case) in order to achieve better OO design.

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.