In the networking code, you may have noticed that there are different types
of exceptions, but you didn't know what they're for.
Now we haven't formally talked about them, so let's do that now.
The first time you saw and exception was in the first course in the nano degree
when we were building the Just Java coffee ordering app.
Now the app ran into an exception and crashed.
To debug the program, we opened up the Android logs
to reveal the stack trace and then discovered an IllegalStateException
was thrown when the submitOrder method could not be found in the main activity.
Let's look at some documentation about exceptions.
When the Java method fails, or runs into an unexpected state,
it can throw an exception, short for an exceptional event.
Exceptions are basically errors, but they're also captured or
wrapped in actual instances of the exception class, which holds information
about what went wrong and what was happening in the system at the time.
If you look here on the left for
example, you'll also notice that there are more specific types of exceptions
that actually extend from the Exceptions super class.
A great example of inheritance in use in the Java framework.
In other words,
all of these specific classes are subclasses of the base class Exception.
For example, here we have an IllegalStateException or
a NullPointerException.
We also saw the SecurityException earlier in this lesson,
when the Internet permission was missing from our Soonami App.
Now you could create a new exception class for your own purposes.
For example, we can create an InvalidEarthquakeException and
define it as we normally would.
Create a custom class and
then have that custom class just extend from the base Exception class.
>From there, we can customize the Exception to hold say,
very specify information about an invalid earthquake scenario.
So as a developer you can write a method that declares that it will
throw an exception.
Meaning that the code inside that method either one, generates and
exception to indicate a unique condition, or two,
and more commonly, calls a method that throws an exception.
Meaning that the Android runtime tried to execute some code, but ran into
a problem and therefore gave notice of the problem by throwing the exception.
It's also important to note that if an exception is thrown, it also means
that the code following the line that caused the exception won't get executed.
So how do you do this in Java code?
There are two distinctions that I'd like you to pay attention to.
Number one, anywhere in your Java code where you want to cause or
invoke an exception, you use the key word throw.
Like in this example here,
where we want to throw an InvalidPurchase Exception(); because we
detected that something went wrong within our completePurchase() method.
Number two, and this is much more subtle.
Anytime our code throws an exception that isn't a descendant of the error or
runtime Exception classes, we must explicitly declare in our method's
signature that our method could throw such an exception.
In Java programming speak, this is known as a checked exception and
has the implication that any code that calls or uses our method
must handle the exception i.e., call our method in a try block.
This is enforced by the Java compiler,
in other words whoever calls the completePurchase method has to have
a backup plan if the InvalidPurchase Exception is thrown or occurs.
We'll talk about how to handle exceptions in the next video.
In case you'd like to learn more about unchecked versus checked Eeceptions
in more detail, see the tutorial linked in the notes below this video.
One more important note.
Just because there's a standard framework for
how to use Exceptions in Java, it doesn't mean that you should throw
exceptions every time something goes wrong.
This is where developer discretion comes into play.
Ideally, if we discover a problem or a unique situation, we should try and
handle it gracefully in code.
By just falling back to some reasonable default behavior for example, and
continuing executing if possible.
We call this failing silently.
However, should we deem that it be more detrimental to keep going with an error
state, then we may decide it's best to notify our calling code of the error
by throwing exception.
We've seen this in play already.
In the case of our Soonami App, when we tried to request earthquake data from
the internet, the Android framework code threw a SecurityException.
This is a case when it's better to throw an exception and
crash the app as opposed to continuing without the Internet permission.
Now if the Android framework code had failed silently,
then we as developers would probably be super confused
as to why we did receive response from the server.
In the case of the Soonami and Quick Report Apps, we won't actually be
creating our own custom exceptions or throwing exceptions intentionally.
We will however be calling the Android framework code that does throw exception
and we'll need to handle those exceptions appropriately.
Let's talk about that next.