Rethrowing exception just as an information I have something like that:


My custom exception class:

public class SolvableException extends RuntimeException {

    protected boolean solved = false;

    public SolvableException(String message) {
        super(message);
    }

    public void setSolved() {
        this.solved = true;
    }

    public boolean isSolved() {
        return this.solved;
    }
}

Class for some very specific calculations which in some unpredictable cases throws my exception:

class VerySpecificCalculator {
    public void makeSomeSpecificCalculations(double someParameter){
        // make some actions...
        // Now I have to make some specific calculations, but sth wrong happend and I do know what to do with it in this place...
        throw new SolvableException("Something wrong happend... Problem with XYZ");
    }
}

My very specific calculator is used in other class and provides some part of its logic:

class Calculator {
    public void makeSomeCalculations(double someParameter){
        // Some variuos calculations...
        VerySpecificCalculator calc = new VerySpecificCalculator();
        try {
            calc.makeSomeSpecificCalculations(4.34);
        } catch (SolvableException e){
            // I know what to do here, so I'm fixing a bug on this level:
            // some fixing code, some rollback whatever...
            e.setSolved();
            // But I want to inform, that the fixing process took place...
            throw e;
        }
    }
}

I use the entire stuff as follows:

class Test {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        try {
            calculator.makeSomeCalculations(344.47);
        }catch (SolvableException e){
            if(e.solved){
                System.out.println("Ok, there was a problem but it has been solved... You can display some JOptionPane to inform a user if you want...");
            } else {
                System.out.println("Buuu, there was a problem an it's still not solved... Action is interrupted ");
                return;
            }
        }
    }
}



Is this approach reasonable? I mean, is it ok to rethrow an exception if the problem has been already solved, and rethrowing plays only some informative role like in my example?

Let's consider such a situation (without rethrowing):

public void f(){
        try {
            methodCausingException();
        } catch (SolvableException e) {
            // fixing code...
        }
        //
        // Code executed when problem is fixed...
        //
    }


But with rethrowing I need to duplicate my code:

public void f(){
        try {
            methodCausingException();
        } catch (SolvableException e) {
            // fixing code...
            e.setSolved();
            //
            // Code executed when problem is fixed...
            //
            throw e;
        }
        //
        // Code executed when problem is fixed...
        //
    }


I can use a finally block, but I don't find this place as good for business logic code.
Especially if you expect these exceptions to occur (relatively) often, I think that using exceptions is a bad idea here. Exceptions should not be used for regular flow of control, this applies to Java as well. Creating and throwing exceptions is among the most costly operations there is in many programming languages.

One comment especially that caught my attention was: "Now I have to make some specific calculations, but sth wrong happend and I do know what to do with it in this place..." If you know what to do with it, then why are you throwing an exception? If you look in the dictionary an exception is:


  special case, departure, freak, anomaly, inconsistency, deviation, quirk, oddity, peculiarity, irregularity" (+ exclusion, omission, objection).


Is your case really an anomaly? (Doesn't sound like it but I can't make this decision for you)

Instead, consider creating a CalculationResult class, which can be returned from your methods. The class can contain your solved variable (possibly among other things). Then when a method has returned a CalculationResult to it's caller, you can read the CalculationResult and decide what to do with it.