This text summarizes the fundamentals of how try-catch-finally term error handling functions. The illustrations are in Java, but the principles are identical for C#. The only big difference between Java and C# conditions is the fact that C# does not have checked exceptions. Checked and unchecked exceptions are described in greater depth in another text.

Conditions are employed in an application to indicate that some malfunction or special scenario has happened, which it does not make sense to carry on the application flow until the exception is managed. A process might throw an exclusion for several reasons, for example if the input variables are invalid (negative when anticipating favorable etc.).
The Decision Stack Described

This text describes the notion the “call stack” in a few areas. By the decision stack is designed the series of method calls in the present approach and again to the Main procedure of this system. In case a procedure A calls B, and B calls C then the phone call stack resembles this:

When an exception is thrown the process stops performance following the “throw” statement. Any claims following the “toss” statement will not be ran. In the illustration above the “get back numberToDivide / numberToDivideBy;” declaration isn’t executed if your BadNumberException is tossed. This program resumes execution when the exception is caught someplace by a “catch” prevent. Getting exceptions is described afterwards.

It’s possible for you to throw any kind of exclusion out of your signal, provided that your approach signature holds it. You may also make up your own personal conditions. Exceptions are regular Java classes that expands java.lang. Exception, or the additional integral different types. If a procedure reports that it tosses an different A, then additionally it is lawful to toss sub classes of A.

Throwing Exceptions:

In case a technique calls yet another technique that tosses checked conditions, the contracting approach is compelled to both move the different on, or capture it. Getting the exception is completed utilizing a try-catch prevent. Listed here is an illustration:

public void divide(int numberToDivide, int numberToDivideBy)
    throws BadNumberException{
        if(numberToDivideBy == 0){
            throw new BadNumberException("Cannot divide by 0");
        }
        return numberToDivide / numberToDivideBy;
    }
When an exception is thrown the process stops performance following the "throw" statement. Any claims following the "toss" statement will not be ran. In the illustration above the "get back numberToDivide / numberToDivideBy;" declaration isn't executed if your BadNumberException is tossed. This program resumes execution when the exception is caught someplace by a "catch" prevent. Getting conditions is described afterwards.

It's possible for you to throw any kind of exclusion out of your signal, provided that your technique unique holds it. You may also make up your own personal conditions. Exceptions are regular Java classes that expands java.lang. Exception, or the additional integral different types. If a procedure reports that it tosses an different A, then additionally it is lawful to toss sub classes of A.
Finding Exceptions

In case a technique calls yet another technique that tosses checked conditions, the contacting process is compelled to both move the different on, or capture it. Getting the exception is completed utilizing a try-catch prevent. Listed here is an illustration:
public void callDivide(){
        try {
            int result = divide(2,1);
            System.out.println(result);
        } catch (BadNumberException e) {
            //do something clever with the exception
            System.out.println(e.getMessage());
        }
        System.out.println("Division attempt done");
    }
The BadNumberException parameter e in the catch-clause factors to the exclusion chucked in the split procedure, if an different is tossed.

If no exeception is thrown by some of the strategy called or assertions ran inside the try-block, the capture-prevent is just dismissed. It is going to not be ran.

If an different is tossed inside the try-prevent, as an example from the split process, the application movement of the phoning process, callDivide, is disrupted simply like the software circulation inside divide. The application circulation restarts at a catch-block in the phone call stack that may get the chucked different. In the illustration above the "System.out.println(outcome);" assertion is not going to get executed in case an different is chucked fromt the split process. As an alternative application performance may restart inside the "grab (BadNumberException e) " block.

If an different is tossed inside the catch-prevent and that different just isn't captured, the capture-prevent is disrupted simply like the try-prevent might have now been.

When the catch prevent is completed the application continues with any claims pursuing the catch prevent. In the illustration above the "System.out.println("Section effort completed");" declaration may always get executed.
Propagating Exceptions

There isn't to get exclusions chucked from additional systems. If you can't do something about the exclusion where the approach tossing it's known as, you can simply allow the system multiply the different up the c-all stack to the technique that called this technique. Should you so the process contacting the technique that tosses the exclusion must state to toss the exclusion. Here is the method by which the callDivide() method might try that circumstance.

See the method by which the try-catch prevent is eliminated, as well as the callDivide technique today expresses that it may toss a BadNumberException. The application delivery is nevertheless disrupted if an exception is chucked from your split technique. So the "System.out.println(outcome);" method isn't going to get executed in case an exclusion is chucked from your split technique. But today the application delivery just isn't restarted inside the callDivide system. The exclusion is spread to the approach that calls callDivide. Application performance does not restart till a grab-prevent somewhere in the c-all stack draws the exclusion. All procedures in the c-all stack between the approach hurling the exclusion and the strategy finding it have their delivery ceased at the stage in the signal where the different is chucked or disseminated.
Example: Finding IOException's

If an different is chucked throughout a collection of assertions in the try-catch prevent, the series of statements is disrupted and the movement of get a grip on may jump immediately to the get-prevent. This signal may be disrupted by conditions in a few areas:

If the reader.read() approach c-all punches an IOException, the next System.out.println((char) i ); isn't ran. Neither is the last reader.close() or the System.out.println("--- File Ending ---"); statements. As an alternative the application jumps straight to the catch(IOException e) ... catch terms. If the newest FileReader("someFile"); constructor call throws an exclusion, n one of the signal inside the try-prevent is executed.
Illustration: Propagating IOException's

This signal is a variant of the preceding technique that punches the conditions as an alternative to getting them:

If an different is tossed from your reader.read() approach then program delivery is stopped, and the different is passed up the decision stack to the technique that called open-file(). If the phoning process h-AS a try-catch prevent, the exception may be captured there. If the contacting process additionally simply punches the system on, the phoning process can also be disrupted at the open-file() technique c-all, and the exclusion offered up the c-all stack. The different is disseminated up the c-all stack such as this until some process gets the different, or the Java Digital Machine does.
Eventually

It's possible for you to connect a finally-term into a try-catch prevent. The code in the finally term will be executed, also if an exclusion is tossed from within the try or catch block. If your signal h-AS a return statement in the try or catch prevent, the signal inside the finally-prevent may get executed before returning from your procedure. Here is what sort of finally terms appears:

    public void openFile(){
        FileReader reader = null;
        try {
            reader = new FileReader("someFile");
            int i=0;
            while(i != -1){
                i = reader.read();
                System.out.println((char) i );
            }
        } catch (IOException e) {
            //do something clever with the exception
        } finally {
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    //do something clever with the exception
                }
            }
            System.out.println("--- File End ---");
        }
    }

No matter whether an exception is thrown or not inside the try or catch block the code inside the finally-block is executed. The example above shows how the file reader is always closed, regardless of the program flow inside the try or catch block.

Note: If an exception is thrown inside a finally block, and it is not caught, then that finally block is interrupted just like the try-block and catch-block is. That is why the previous example had the reader.close() method call in the finally block wrapped in a try-catch block:

    } finally {
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    //do something clever with the exception
                }
            }
            System.out.println("--- File End ---");
        }

That way the System.out.println(“— File End —“); method call will always be executed. If no unchecked exceptions are thrown that is. More about checked and unchecked in a later chapter.

You don’t need both a catch and a finally block. You can have one of them or both of them with a try-block, but not none of them. This code doesn’t catch the exception but lets it propagate up the call stack. Due to the finally block the code still closes the filer reader even if an exception is thrown.

    public void openFile() throws IOException {
        FileReader reader = null;
        try {
            reader = new FileReader("someFile");
            int i=0;
            while(i != -1){
                i = reader.read();
                System.out.println((char) i );
            }
        } finally {
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    //do something clever with the exception
                }
            }
            System.out.println("--- File End ---");
        }
    }

Notice how the catch block is gone.

Catch or Propagate Exceptions?

You might be wondering whether you should catch or propagate exceptions thrown in your program. It depends on the situation. In many applications you can’t really do much about the exception but tell the user that the requested action failed. In these applications you can usually catch all or most exceptions centrally in one of the first methods in the call stack. You may still have to deal with the exception while propagating it though (using finally clauses). For instance, if an error occurs in the database connection in a web application, you may still have to close the database connection in a finally clause, even if you can’t do anything else than tell the user that the action failed. How you end up handling exceptions also depends on whether you choose checked or unchecked exceptions for your application. There is more on that in other texts in the error handling trail.

Leave a Reply

Your email address will not be published. Required fields are marked *