Related
I have been coding in Java for a while now. But sometimes, I don't understand when I should throw the exception and when should I catch the exception. I am working on a project in which there are lot of methods. The hierarchy is something like this-
Method A will call Method B and Method B will call some Method C and Method C will call Method D and Method E.
So currently what I am doing is- I am throwing exceptions in all the methods and catching it in Method A and then logging as an error.
But I am not sure whether this will be the right way to do it? Or should I start catching exceptions in all the Methods. So that is why this confusion started in my- When should I catch the Exception vs When should I throw the exceptions. I know it's a silly question but somehow I am struggling to understand this major concept.
Can someone give me a detailed example of When to catch the Exception vs When to throw the Exceptions so that my concepts gets cleared on this? And in my case, should I keep on throwing the exception and then catch it in the main calling Method A?
You should catch the exception when you are in the method that knows what to do.
For example, forget about how it actually works for the moment, let's say you are writing a library for opening and reading files.
So you have a class, say:
public class FileInputStream extends InputStream {
public FileInputStream(String filename) { }
}
Now, lets say the file doesn't exist. What should you do? If you're struggling to think of the answer, that's because there isn't one... the FileInputStream doesn't know what to do about that problem. So it throws it up the chain, i.e.:
public class FileInputStream extends InputStream {
public FileInputStream(String filename) throws FileNotFoundException { }
}
Now, lets say someone's using your library. They might have code that looks like this:
public class Main {
public static void main(String... args) {
String filename = "foo.txt";
try {
FileInputStream fs = new FileInputStream(filename);
// The rest of the code
} catch (FileNotFoundException e) {
System.err.println("Unable to find input file: " + filename);
System.err.println("Terminating...");
System.exit(3);
}
}
}
Here, the programmer knows what to do, so they catch the exception and handle it.
There are two cases when you should catch an exception.
1. At the lowest possible level
This is the level at which you are integrating with third party code, such as an ORM tool or any library performing IO operations (accessing resources over HTTP, reading a file, saving to the database, you name it). That is, the level at which you leave your application’s native code to interact with other components.
At this level, unexpected problems out of your control such as connection failures and locked files may occur.
You may want to handle a database connection failure by catching a TimeoutException so that you can retry after a few seconds. The same goes for an exception when accessing a file, which may be locked by a process at the moment but be available at the next instant.
The guidelines in this scenario are:
Handle only specific exceptions, such as SqlTimeoutException or IOException. Never handle a generic exception (of type Exception)
Handle it only if you have something meaningful to do about it, such as retries, triggering compensatory actions, or adding more data to the exception (e.g. context variables), and then re-throw it
Do not perform logging here
Let all other exceptions bubble up as they will be handled by the second case
2. At the highest possible level
This would be the last place where you can handle the exception before it is thrown directly to the user.
Your goal here is to log the error and forward the details to the programmers so they can identify and correct the error. Add as much information as possible, record it, and then show an apology message to the user, as there’s probably nothing they can do about it, especially if it is a bug in the software.
The guidelines in this second scenario are:
Handle the generic Exception class
Add more information from current execution context
Log the error and notify the programmers
Show an apology to the user
Work it out as soon as you can
The reasoning behind these guidelines
First, is that exceptions represent irreversible errors. They represent represent a bug in the system, a mistake made by the programmers, or a situation beyond the control of the application.
In these cases, there is usually little or nothing the user can do. Thus, the only thing you can do is log the error, take the necessary compensatory actions, and apologize to the user. If it is a mistake that the programmers made, it is best to let them know and fix it, working towards a more stable version.
Second, try catch blocks can mask application execution flow depending on how they are used. A try catch block has a similar function to that of a label and its goto companion, which causes the application execution flow to jump from one point to another.
When to throw exceptions
Easier to explain in the context of developing a library. You should throw when you reached an error and there's nothing more you can do besides letting the consumer of your APIs know about it, and letting them decide.
Imagine you're the developer of some data access library. When you reach a network error, there's nothing you can do besides throwing an exception. That's an irreversible error from a data access library standpoint.
This is different when you're developing a website. You would likely catch such exception in order to retry, but would want to throw an exception in case you received invalid parameters from outer layers since they should have been validated there.
Which is again different in a Presentation layer, where you expect the user to provide invalid parameters. In that case you just show a friendly message instead of throwing an exception.
As featured at https://roaddd.com/the-only-two-cases-when-you-should-handle-exceptions/
An exception should be thrown when a function experiences a failure, i.e., an error.
A function is a unit of work, and failures should be viewed as errors or otherwise based on their impact on functions. Within a function f, a failure is an error if and only if it prevents f from meeting any of its callee’s preconditions, achieving any of f’s own postconditions, or reestablishing any invariant that f shares responsibility for maintaining.
There are three different kinds of errors:
a condition that prevents the function from meeting a precondition (e.g., a parameter restriction) of another function that must be called;
a condition that prevents the function from establishing one of its own postconditions (e.g., producing a valid return value is a postcondition); and
a condition that prevents the function from re-establishing an invariant that it is responsible for maintaining. This is a special kind of postcondition that applies particularly to member functions. An essential postcondition of every non-private member function is that it must re-establish its class’s invariants.
Any other condition is not an error and should not be reported as an error.
Report an error wherever a function detects an error that it cannot deal with itself and that prevents it from continuing in any form of normal or intended operation.
Handle the error in the places that have sufficient knowledge to handle the error, to translate it, or to enforce boundaries defined in the error policy, such as on main or thread mainlines.
Source: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
In general, catch at the level where you can do something useful about it. For example, user is trying to connect to some database, and it fails in Method D.
How do you want to handle it? Perhaps by putting up a dialog saying "Sorry, cannot connect to SERVER/DB" or whatever. Is is method A, B, or C that created this SERVER/DB information (say, by reading a settings file or asking for user input) and tried the connection? That is probably the method that should handle the Exception. Or at least 1 away from the method that should handle it.
It really varies depending on your application, so this can only be very general advice. Most of my experience is with Swing / desktop apps, and you can usually get a feel based on which classes are doing program logic (e.g. "Controller" stuff) and who is putting up dialog boxes (e.g. "View" stuff). Usually the "controller" should catch the exception and try to do something.
In a web app this can be different.
Some very skeletal code, most of the classes do not exist, and Im not sure if a URL for the DB even makes sense, but you get the idea. Vaguely Swingish...
/* gets called by an actionListener when user clicks a menu etc... */
public URL openTheDB() {
URL urlForTheDB = MyCoolDialogUtils.getMeAURL(URL somePreviousOneToFillInTheStart);
try {
verifyDBExists(urlForTheDB);
// this may call a bunch of deep nested calls that all can throw exceptions
// let them trickle up to here
// if it succeeded, return the URL
return urlForTheDB;
}
catch (NoDBExeption ndbe) {
String message = "Sorry, the DB does not exist at " + URL;
boolean tryAgain = MyCoolDialogUtils.error(message);
if (tryAgain)
return openTheDB();
else
return null; // user said cancel...
}
catch (IOException joe) {
// maybe the network is down, aliens have landed
// create a reasonable message and show a dialog
}
}
I'll share a pattern that has saved my bacon in a production environments or two.
Motivation
My aim is to ensure that the poor dude (maybe me) who is in at midnight trying to resolve a sev1 support ticket, gets a nice hierarchy of 'caused by' errors to follow, complete with data such as ID's, all without over cluttering the code.
Method
To achieve this, I catch all checked exceptions and re-throw them as unchecked exceptions. I then use a global catch at the boundary of each of my architectural layers (usually abstracted or injected so it is only ever written once). It is at these points that I can add extra context to the error stack, or decide whether to log and ignore, or raise a custom checked exception with variables to hold any extra context. On an aside, I only log errors at the top layer to stop 'double logging' from occurring (e.g. the cron job, the spring controller for ajax)
throw new RuntimeException(checked,"Could not retrieve contact " + id);
With this approach there is no cluttering of your GUI or business tier's method signatures by having to declare 'throws' for database related exceptions.
An Example of how this works in Real Life:
Lets say my code's job is an automated process to renew many insurance policies. The architecture supports a GUI to manually trigger renewal for one policy. Lets also say that the postcode for the rating area is corrupted in the DB for one of these policies.
An example of the type of error log I would want to achieve would be.
Log message: Flagging policy 1234 for manual intervention due to error:
From Stack Trace: Error Renewing Policy 1234. Rolling back the transaction ... This catch would also cover errors such as save errors, or generation of a letter.
From Stack Trace: Caused by: Error Rating Policy 1234 ... This catch would pickup errors retrieving many other objects, and algorithm errors such as NPE etc...
From Stack Trace: Caused by: Error Retrieving Rating Area 73932 ...
From Stack Trace: Caused by: JPA: unexpected null in field 'postcode'
You should handle the exception at the lowest possible level. If method can't handle the exception properly you should throw it.
catch If you have method which connects to resource (eg opens file/network)
throw if class higher in hierarchy needs information about error
You generally throws an exception when you want to notify the caller of the method of some failures.
e.g invalid user input, database problems, network outages, absent files
As others have said, as a general rule, you should catch an exception when you can actually handle it, otherwise, just throw it.
For example, if you are writing code that reads information about a connecting player from a save file and one of your I/O methods throws an IOException, then you would want to throw that exception and the code that invoked the load method would want to catch that exception and handle it accordingly (like disconnect the player, or send a response to the client, etc.). The reason why you would not want to handle the exception in the load method is because in the method, you cannot meaningfully handle the exception, so you delegate the exception to the caller in hope that they can handle it.
I use JOOQ for querying my relational database, I've recently been looking at the connection handling and its confusing me a little. I've tried reading the JavaDoc and also this: When is a Connection closed when calling JooQ DSLContext's .close(), if at all? but its creating even more FUD for me.
Currently my code does this:
try (final Connection cn = pool.getConnection()) {
DSLContext dsl = DSL.using(cn, MARIADB);
// query stuff
}
Essentially I'm treating JOOQ as just a querier that doesn't do connection handling at all. I've never had problems with this code.
However, I do get warnings from IntelliJ saying that DSLContext is AutoClosable and should be handled by a try-with-resources. I know it doesn't have to in this case but my first question is 'Can it?'. Is it safe to replace the above code with this instead:
try (final DSLContext dsl = DSL.using(pool.getConnection(), MARIADB)) {
// query stuff
}
The other StackOverflow post said that you need to use close() on the DSLContext when you have created it using one of the helper methods. But what if you just passed the Connection object in? Will the close() still close my connection?
I also found that DSL has another using() that allows you to assign an entire DataSource. So instead I could also do this:
final DSLContext dsl = DSL.using(pool, MARIADB);
and then just leave out all the try-with-resources entirely. What are trade-offs here? Are there any even?
IntelliJ further complained about an UpdateQuery that has the AutoClosable interface (inherited from Query). Is it necessary to close my queries? I've always just called execute() and closed the underlying connection without problems.
What I am looking for is code that will satisfy these four requirements
It uses correct resource management
It uses JOOQ
The try-with-resources warning is turned on in the IDE
There are no warnings
The various pieces of code above all fail at least one of those requirements. But ultimately the connection handling doesn't matter that much because the query classes in JOOQ also generate tons of warnings.
The best way is indeed to turn the warning off, but then for JOOQ specifically using Intellij's exclusion rules. How to do this is mentioned in a comment on the page that Lukas linked too (https://blog.jooq.org/2015/12/02/a-subtle-autocloseable-contract-change-between-java-7-and-java-8/).
I'll just have to remember to do things the right way for JOOQ classes :)
Currently my code does this:
try (final Connection cn = pool.getConnection()) {
DSLContext dsl = DSL.using(cn, MARIADB);
// query stuff
}
That's correct usage.
Essentially I'm treating JOOQ as just a querier that doesn't do connection handling at all.
That's a correct assumption.
However, I do get warnings from IntelliJ saying that DSLContext is AutoClosable and should be handled by a try-with-resources
Many IDEs do this check, but it's usually best to turn them off. In Java 8+, you cannot reasonably expect an AutoCloseable to really need closing. One such example is Stream, which is AutoCloseable for those cases where it really does contain a resource, but mostly it doesn't.
This was a subtle API change in Java 8, leading to this warning in IDEs best being turned off (or you can maybe specify exceptions).
Your questions:
Is it safe to replace the above code with this instead:
try (final DSLContext dsl = DSL.using(pool.getConnection(), MARIADB)) {
// query stuff
}
Yes, you can do that. The DSLContext.close() call will only close resources that were created by DSLContext. In your case, it does not have any effect.
For the record, resourceful DSLContexts are created, e.g. by DSL.using(url, username, password)
and then just leave out all the try-with-resources entirely. What are trade-offs here? Are there any even?
All of this has really nothing to do with resources.
IntelliJ further complained about an UpdateQuery that has the AutoClosable interface (inherited from Query). Is it necessary to close my queries? I've always just called execute() and closed the underlying connection without problems.
turn off that warning! :-)
queries can be resourceful when calling Query.keepStatement(true)
A quite theoretical question this time. So I'm using this function in Eclipse:
CsvReader csv = new CsvReader("src/maindroite.csv");
Which can't run because "Unhandled exception type FileNotFoundException". Ok, I understand that I have to add something for the case where the file doesn't exist, at which point I usually add a few lines to catche the exception and throw it away. But my question is: why do I need to catch the exception even when the file do exist? And actually, why do I even have this Exception thing for some functions and not others?
For example, let's say I'm trying to run:
ImageIcon icon1 = new ImageIcon("src/square.jpg");
ImageIcon icon2 = new ImageIcon("src/circle.jpg");
Where "square.jpg" exists but not "circle.jpg". The program will create icon1, but not icon2, because it can't. But I don't need to add an ExceptionHandler for the case where the image doesn't exist. What is the difference between both functions?
To sum it up:
Why do I have to add an ExceptionHandler when the file do exist?
Why do I have to add an ExceptionHandler for some functions and not others?
Thanks!
Why do I have to add an ExceptionHandler when the file do exist?
Basically you have to add it regardless, because you cannot write conditional code like that, in short there is no way that for the compiler to know before runtime if the file exists or not, therefore the compiler forces yo to put a try/catch block, since FileNotFoundException is a checked exception.
Why do I have to add an ExceptionHandler for some functions and not others?
You only have to add try/catch blocks to anything that throws a checked exception, that is anything that does **NOT* inherit from RuntimeException or Error classes. Subclasses of Error and RuntimeException are not checked exceptions and you may either put the try/catch or not the compiler does not care. Since the constructor for ImageIcon does not throw any kind of exceptions and will simply return null if the image does not exist there is no need to do a try/catch block.*
Even if the file exists now, on your system, it might not exist later. Or you may give this code to someone who doesn't have src/square.jpg. Or maybe there will be a hardware malfunction where something on your hard drive gets corrupted and accidentally deletes src/square.jpg. Maybe the user might even just delete the files.
Exception handling in Java forces you to think about what would happen in the worst case if something really bad happens (like src/square.jpg goes missing). Do you crash? Is it okay to continue on like nothing happened? You get to decide how to handle these failure modes in the catch clause.
Some functions don't require you to handle exceptions because there isn't really anything that could go wrong in the functions that you could be reasonably expected to handle.
1) Why do I have to add an ExceptionHandler when the file do[es] exist?
Because the Java compiler cannot know whether or not that file will actually exist at some arbitrary runtime. (Suppose the file was deleted after you compiled but before you ran the program?) Basically, your code must always have the logic required to handle conditions which aren't expected to happen but might anyway.
2) Why do I have to add an ExceptionHandler for some functions and not others?
There could be various reasons but here's the one you're probably seeing. Exceptions are thrown per method but caught per try/catch block or per method if they are propagated upwards. In your example, you could wrap each call to the ImageIcon constructor in its own try/catch block or both together, depending on what you want to do:
try {
icon1 = new ImageIcon("f1.jpg");
} catch (Exception e) { /* Handle the case for missing "f1.jpg". */ }
try {
icon2 = new ImageIcon("f2.jpg");
} catch (Exception e) { /* Handle the case for missing "f2.jpg". */ }
Compared to:
try {
icon1 = new ImageIcon("f1.jpg");
icon2 = new ImageIcon("f2.jpg");
} catch (Exception e) { /* Handle the case for missing "f1" or "f2". */ }
Because Java differentiates between what are known as "checked" and "unchecked" exceptions. It's the source of a lot of heated controversy, as to whether or not unchecked exceptions should even exist, and whether or not API methods should throw exceptions.
According to the Java Trails:
Here's the bottom line guideline: If a client can reasonably be
expected to recover from an exception, make it a checked exception. If
a client cannot do anything to recover from the exception, make it an
unchecked exception.
That's the so-called rationale.
Read more about "the controversy" here.
Why do I have to add an ExceptionHandler when the file do exist?
It exists for now, but there is no guarantee it will there every time. Could happen because of whole lot of reasons. If there is no file, it doesn't make sense to do InputStream and associated business logic and it is sure that your business won't be successful.
Why do I have to add an ExceptionHandler for some functions and not others?
Some Classes like Imageicon, they are not show stoppers for your business processing. If they are not there, that's Ok, you can still continue with your core business logic.
I feel this is main reason why some class mandate exceptions and some are not.
The idea behind checked exceptions is that they make it possible for the caller of a function to know what exceptions might escape from it. You don't have to actually catch the FileNotFoundException if you don't want to, provided you add throws FileNotFoundException to your method signature to let your caller know that such an exception might escape from your method.
The concept is a good one, but unfortunately there's no concise way to state that you want to catch all exceptions that aren't overly severe and wrap them into a common exception type for your caller. In a lot of cases, when an exception occurs, the real message you want to convey is either "the method didn't complete, but the system doesn't seem to be on fire and any side-effects have been undone", or "the method didn't complete, and the system doesn't seem to be on fire, but there may have been other side-effects." It would be helpful if there were a concise syntax to indicate regions of code where exceptions should be caught and wrapped to one of the above formats, but alas there is not.
I was reading some things about exception handling in Java, to be able to write better code. OK, I admit, I am guilty; I've used too much try-catch{} blocks, I've used ex.printStackTrace() in the catch, not even using a proper logger (actually the System.out and System.err were redirected to a PrintWriter, so a log was generated). However, after a few hours of readings, I find myself in a strange place: the unknown. If the exceptions are designed to pass info about abnormal states of flow, how does one know WHERE is the proper level to do something with that info?
For instance, when a database error occurs, should one return a null value or an error code, or throw the exception? If thrown, WHERE should that exception be handled? I understand that is no use even to log an exception if you cant do anything about it. However, in GUI apps, that could easily kill your GUI (I am using SWT and I've seen this too often), even for the case of the menuShown() method (an ArrayIndexOutOfBounds exception will close the app, if not handled). The example could go on forever, but here's the summary of questions:
Does using try-catch() excessively have a negative impact on performance?
Is it better to use specific exception types? What if I missed catching one
of the possible X types of exceptions that could occur?
Frankly, I've heard of and use a mere 10% I think of the Java standard exceptions, in 2-3 years. Yes, someone said that if the caller don't know how to deal with the thrown exceptions, he SHOULD NOT HAVE THE RIGHT to call the throwing method. Is that right?
I've read this article of Anders
Hejlsberg, saying that checked exceptions are bad. Should that indicate that convenient exception swallowing is advised in some cases?
A picture is worth 1000 words; I guess some examples will help a lot
here.
I know the subject is eternal, but actually I am looking forward to review a middle-size project of 150 classes, using your advice. Many thanks.
The general rule of thumb for exception is, if you can do something about it, catch it and handle it, if you can't, re-throw it to the next method. To get into some of your specifics:
No, using excessive try/catch will not have a performance impact
Using the most specific type of exception you can. For example, you shouldn't generally throw Exception if you can avoid it. By throwing a specific type, you are letting the user know what can go wrong. However, you can rethrow it as something more generic so callers that are not concerned with the specific exception don't need to know about it (for example, a GUI won't care if it's an IOException vs an ArrayIndexOutOFBoundsException).
You will find people that like checked exceptions more and you will find people that like unchecked more. In general, I try to use unchecked exceptions because there is generally not a lot you can do about most checked exceptions, and you can still handle unchecked exceptions, you just don't have to. I frequently find myself rethrowing checked exceptions since I can't do much about them (another strategy is to catch a checked exception and rethrow it as an unchecked so classes higher in the chain don't need to catch it if they don't want).
I generally like to log exceptions at the point of where they are caught - even if I can't do anything about it, it helps to diagnose the problem. If you are not familiar with it, also look into the method Thread.setDefaultUncaughtExceptionHandler. This allows you to handle exceptions that are not caught by anyone and do something with it. This is particularly useful with a GUI app since the exception might otherwise not be seen.
To get into some examples:
try {
// some database operation
}
catch (IOException ex) {
// retry the database operation. then if an IO exception occurs rethrow it. this shows an example doing something other than just catch, logging and/or rethrowing.
}
I'll be happy to expand on any parts of this if you'd like.
Many good answers, let me just add a couple of points that haven't been mentioned.
Your exception types should be as specific as a caller is likely to distinguish them. By that I mean, if there are two possible errors, A and B, and any caller is likely to do exactly the same thing in both cases, then make a single exception class. If a caller is likely to do two different things, then make two exception classes.
For many, probably most, of the exceptions that I create, the only thing the program can realistically do is display an error message and give the user the opportunity to change his inputs and try again. Most validation errors -- invalid date format, non-digits in a numeric field, etc --fall into this category. For these I create a single exception type, which I usually call "BadInputException" or "ValidationException", and I use that same exception class throughout the system. When there's an error, I 'throw new BadInputException("Amount must contain only digits")' or some such, and then have the caller display it and let the user retry.
On the other hand, if the caller is reasonably likely to do different things in different cases, make them different exceptions.
Easy rule of thumb: If you have two or more exceptions that are ALWAYS handled with identical, duplicate code, combine them into a single exception. If your catch block is doing additional checking to figure out what kind of error this really is, it should have been two (or more) exception classes. I've seen code that does exception.getMessage and then looks for keywords in the message to figure out what the problem was. This is ugly. Make multiple exceptions and do it cleanly.
There are three good reasons to use exceptions rather than other ways of handling errors.
(a) It avoids the problem of "magic" return values, like non-null string is a real answer but null means there was an error. Or worse, "NF" means file not found, "NV" means invalid format, and anything else is the real answer. With exceptions, an exception is an exception and a return value is a return value.
(b) Exceptions neatly skip the main line of code. Usually when there's an error you want to skip a whole bunch of processing that does not make sense without valid data, and go right to displaying an error message and quitting, or retrying the operation, or whatever is appropriate. In the bad old dies we would write "GOTO panic-abort". GOTOs are dangerous for all the reasons that have been much discussed. Exceptions eliminate what was perhaps the last remaining good reason to use a GOTO.
(c) Perhaps a corrollary to (b), you can handle the problem at the appropriate level. Sometimes when an error happens you want to retry the exact same function -- like an I/O error might represent a transient communications glitch. At the other extreme, you could be ten levels deep in subroutines when you get an error that cannot be handled in any way but bombing out of the entire program and displaying a "sorry, armageddon has occurred, everybody in here is dead" message. With exceptions it's not only easy to choose the correct level, but you can make different choices in different modules.
Exception is there so the programmer of a Task does not have to deal with the problem by himself. (1): In case the problem is NOT LOGICAL to him to handle in the Task.
A task to read a String from a stream should not handle disk error isn't it. But it should be very logical to handle if data does not contain a String.
(2): He can't handle it by himself (not enough info)
A task to read a String from a file and file not found may ask user to select another file but how can the task now what folder the file might be what extension the file might be. Without knowing that, how can the task create a GUI to re-ask that.
(3): There is no logical (or manageable) way to distinguish between different return.
If a task can't read the file and return null. What about if the file in the wrong format, return null too? How can these two differ? Exceptions can be used to differ that. That why it is called an Exception :-D.
(4): There are many similar tasks that need similar handling and writing that in all tasks is hard to maintain.
Writing the handle code for all access can be a mess as you may require many duplications.
interface DBAccess {
public Result accessDB();
}
class DBOperation {
static public void DoOperation(DBAccess pAccess) {
try { return DBAccess.accessDB(); }
catch(InvalidDBPasswordException IPE) {
// Do anything about invalid password
}
catch(DBConnectionLostException DBCLE) {
// Do anything about database connection lost
}
// Catch all possible DB problem
}
}
...
private User[] ShowUserList_and_ReturnUsers() {
// Find the used.
// Show user list
if (Users.count() == 0)
return null;
else return Users;
// No need to handle DB connection problem here
}
private User[] GetUserProfile() {
// Find the used and return
// No need to handle DB connection problem here
}
...
/** An onClick event to show user list */ {
DBOperation.DoOperation(new DBAccess() {
public Result accessDB() {
return ShowUserList_and_ReturnUsers();
}
});
}
/** An onClick event to show a user profile */ {
DBOperation.DoOperation(new DBAccess() {
public Result accessDB() {
return GetUserProfile();
}
});
}
... Many more DB access
(5): Writing all the checking for error complicate or slow down the task.
The above problem should show how can it help reduce the complication. Here is how it help not to slow down.
for(int i = 0; i < Users.length; i++) {
User aUser = Users[i];
// Do something with user
}
Replaced with
try {
for(int i = 0; ; i++) {
User aUser = Users[i];
// Do something with user
}
}
catch(ArrayOutOfBoundException AOBE) {}
The replacement code will be better performance if the number of user is large.
When a database error occurs, should one return a null value, and error code or throw the exception?
Ans: Depending on what kind of error. Like if you can't find a user, that is not an error. But if the password is wrong or the connection is down, these are errors as trying to handle it in a normal way complicate the program.
(1). Using excessive try-catch() has a negative impact on performance?
Ans: According to "Effective Java", it has very very tiny effect (only not good in loop) as far as I remember (I don't have the book with me here now).
(2).
Using specific exception types is better?
Ans: User specific one is better to avoid solving the wrong problem.
What if i missed to catch one of the possible X types of exceptions that could occur? Frankly, I've heard and use a mere 10% i think of the Java standard exceptions, in 2-3 years.
Ans: Just like if you handle the error without exception, You can miss it too. You simply add it in when you find that out.
Yes, someone said that if the caller don't know how to deal with the trowed exceptions, he SHOULD NOT HAVE THE RIGHT to call the throwing method. Is that right?
Ans: No, if I don't know what to do with some exception, re-throw it.
(3). I've read this article of Anders Hejlsberg, saying that checked exceptions are bad. Should that indicate that convenient exception swallowing is advised in some cases?
Ans: I think he is talking about "Checking exception" as a feature for the compiler to ensure that some exception should be handle. The the idea of having exception.
(4). A picture is worth 1000 words..i guess some examples will help a lot here.
Ans: The code above.
I got the run now .... Sorry ... :-p (Be there in a minute, honey!!)
One thing that we have done on our team is to have custom exceptions for our errors. We are using the Hibernate Validator framework, but you can do this with any framework, or stock exceptions.
For example, we have a ValidationException to handle validation errors. We have a ApplicationException to handle system errors.
You DO want to minimize your try-catch-ing. In our case, we will have the validator collect ALL the validations in "InvalidValue" objects, and then throw a single ValidationException with the invalid value information bundled into it. Then you can report to the user which fields were in error, etc.
In the case you mentioned of a database error - you may not want to send the stacktrace to the UI (logging it is a good idea). This is a case where you can catch the database exception, then throw your own ApplicationException to your GUI. Your GUI won't have to know how to deal with an infinite number of server errors, but can be set to deal with the more generalized ApplicationException - possibly reporting that there is a problem with the server, and indicating that the user should contact your customer support department to report the problem.
Lastly, sometimes you can't help but use a lot of try/catch blocks because of the external APIs you rely on. This is fine. As mentioned before, catch the external exception, and format it into one which makes more sense to YOUR application. Then throw the custom exception.
While I don't have any numbers, I don't believe that try-catch has any significant impact on performance (not that I have seen). I think that if you don't run into many exceptions, the performance impact will be basically nothing. But in any case, it's best to care about implementing code correctly first and achieving good performance second -- a lot easier to do the second once the first is done.
I think the exception class should be specific as to what the exception really is. The problem I have with Java's SQLExceptions is that they give you no information about what really went wrong. Spring uses far a set of more descriptive database exceptions (deadlock exceptions, data integrity exceptions, etc.) That way you can tell what the problem really was.
Checked exceptions can be annoying, but I don't think they're always bad. For example, Spring uses unchecked exceptions for database errors, but I still check for them and either 1) handle them right there, if possible, or 2) wrap in a more general exception that the shows that the component failed.
Unfortunately, I can't think of any good specific exceptions. However, like I said, I've found Spring's exception rules to be helpful and yet not annoying, so maybe you could look at some Spring docs. The Spring database classes are a good example.
Using excessive try-catch() has a negative impact on performance?
This sounds like micro optimization and, if this really has a performance impact, you'll have to deal with a lot of bigger performance problems before to face this one.
Using specific exception types is better? What if i missed to catch one of the possible X types of exceptions that could occur? Frankly, I've heard and use a mere 10% i think of the Java standard exceptions, in 2-3 years. Yes, someone said that if the caller don't know how to deal with the trowed exceptions, he SHOULD NOT HAVE THE RIGHT to call the throwing method. Is that right?
I'm not sure I understood the question but I'd say: "If you don't know what to do with an exception, re-throw it".
I've read this article of Anders Hejlsberg, saying that checked exceptions are bad. Should that indicate that convenient exception swallowing is advised in some cases?
Hell no. This just means that unchecked exception should be preferred in some cases especially when the user won't know what to do with a checked exception (e.g. SQL exception), or if there is not possible recovery,...
A picture is worth 1000 words..i guess some examples will help a lot here.
Spring's DataAccessException is a very good example. Check chapter 10. DAO support.
se-radio made a podcast episode about that topic of error handling that explains some philosophy about how to use exceptions, which can be restated as "Where to absorb them".
The main thing I retained is that most functions should let them bubble up, and most exceptions details should end up in a log file. Then the functions pass only global messages saying that something happened.
In a sense, this leads to a sort of exception hierarchy : one for each layer of code.
As I think they said, it doesn't make sense to explain to the user that such DB cluster failed because the DNS was unavailable, or because the disk was full. At that level, something happend that couldn't allow the transaction to complete, that's all the user has to know.
Of course, the developpers/administrators will be happy to see more details, that's why at the DB layer, the specific exceptions should be logged.
Return value vs. throwing an exception
The fundamental difference between an exception and a return value is that the return value is delivered to your immediate caller, whereas an exception is delivered to a catch clause anywhere in the call stack. This allows to reuse the same exception handler for many different kinds of exceptions. I recommend that you favor exceptions over return codes if and only if you need that feature.
Performance impact.
Every instruction has a negative effect on performance, including those in catch-blocks. However, any modern CPU can throw and handle millions of exceptions per second, so unless you throw thousands of them you won't notice a thing.
Specific exceptions
For throwing, be specific to allow specific handling.
For handling, you can be generic, but you should be aware that arbitrary exceptions can be delivered to your handler, including unchecked ones not declared by your callees.
checked
The debate rages whether methods should use checked or unchecked exceptions.
Never just swallow an exception. Handle or rethrow it. It simplifies maintenance if you don't discard evidence about failures.
Example
An application I worked on recently receives commands over the network which it then executes. This usually involves further interaction with remote systems, which might fail for a host of reasons. The methods to carry out the command don't catch any exceptions, letting them bubble of the call stack to the central exception handler in the command listener, which does the following:
for (int retries = 0;; retries++) {
try {
commandService.execute(command);
return;
} catch (Exception e}
Log.error(e);
if (retries < 3) {
continue;
} else {
saveForAnalysis(command, e);
alertOperator();
return;
}
}
}
We intentionally did not catch & rethrow exceptions in the processing logic, as we felt this would have added no value.
Please, do not return null in case of non-fatal errors. Return a NullObject instead.
Otherwise you need a null check after each and every call to your code which is a pain, and if forgotten will cause the code to crash.
In Java (or any other language with checked exceptions), when creating your own exception class, how do you decide whether it should be checked or unchecked?
My instinct is to say that a checked exception would be called for in cases where the caller might be able to recover in some productive way, where as an unchecked exception would be more for unrecoverable cases, but I'd be interested in other's thoughts.
Checked Exceptions are great, so long as you understand when they should be used. The Java core API fails to follow these rules for SQLException (and sometimes for IOException) which is why they are so terrible.
Checked Exceptions should be used for predictable, but unpreventable errors that are reasonable to recover from.
Unchecked Exceptions should be used for everything else.
I'll break this down for you, because most people misunderstand what this means.
Predictable but unpreventable: The caller did everything within their power to validate the input parameters, but some condition outside their control has caused the operation to fail. For example, you try reading a file but someone deletes it between the time you check if it exists and the time the read operation begins. By declaring a checked exception, you are telling the caller to anticipate this failure.
Reasonable to recover from: There is no point telling callers to anticipate exceptions that they cannot recover from. If a user attempts to read from an non-existing file, the caller can prompt them for a new filename. On the other hand, if the method fails due to a programming bug (invalid method arguments or buggy method implementation) there is nothing the application can do to fix the problem in mid-execution. The best it can do is log the problem and wait for the developer to fix it at a later time.
Unless the exception you are throwing meets all of the above conditions it should use an Unchecked Exception.
Reevaluate at every level: Sometimes the method catching the checked exception isn't the right place to handle the error. In that case, consider what is reasonable for your own callers. If the exception is predictable, unpreventable and reasonable for them to recover from then you should throw a checked exception yourself. If not, you should wrap the exception in an unchecked exception. If you follow this rule you will find yourself converting checked exceptions to unchecked exceptions and vice versa depending on what layer you are in.
For both checked and unchecked exceptions, use the right abstraction level. For example, a code repository with two different implementations (database and filesystem) should avoid exposing implementation-specific details by throwing SQLException or IOException. Instead, it should wrap the exception in an abstraction that spans all implementations (e.g. RepositoryException).
From A Java Learner:
When an exception occurs, you have to
either catch and handle the exception,
or tell compiler that you can't handle
it by declaring that your method
throws that exception, then the code
that uses your method will have to
handle that exception (even it also
may choose to declare that it throws
the exception if it can't handle it).
Compiler will check that we have done
one of the two things (catch, or
declare). So these are called Checked
exceptions. But Errors, and Runtime
Exceptions are not checked for by
compiler (even though you can choose
to catch, or declare, it is not
required). So, these two are called
Unchecked exceptions.
Errors are used to represent those
conditions which occur outside the
application, such as crash of the
system. Runtime exceptions are
usually occur by fault in the
application logic. You can't do
anything in these situations. When
runtime exception occur, you have to
re-write your program code. So, these
are not checked by compiler. These
runtime exceptions will uncover in
development, and testing period. Then
we have to refactor our code to remove
these errors.
The rule I use is: never use unchecked exceptions! (or when you don't see any way around it)
There’s a case for the opposite: never use checked exceptions. I’m reluctant to take sides in the debate (there’s definitely good arguments on both sides!) but a fair number of experts feel that checked exceptions were a wrong decision in hindsight.
For some discussion, check the WikiWikiWeb’s “Checked exceptions are of dubious value”. Another example of an early, extensive argument is Rod Waldhoff’s blog post.
On any large enough system, with many layers, checked exception are useless as, anyway, you need an architectural level strategy to handle how the exception will be handled (use a fault barrier)
With checked exceptions your error handling stategy is micro-managed and its unbearable on any large system.
Most of the time you don't know if an error is "recoverable" because you don't know in what layer the caller of your API is located.
Let's say that I create a StringToInt API that converts the string representation of an integer to an Int. Must I throw a checked exception if the API is called with the "foo" string ? Is it recoverable ? I don't know because in his layer the caller of my StringToInt API may already have validated the input, and if this exception is thrown it's either a bug or a data corruption and it isn't recoverable for this layer.
In this case the caller of the API does not want to catch the exception. He only wants to let the exception "bubble up". If I chose a checked exception, this caller will have plenty of useless catch block only to artificially rethrow the exception.
What is recoverable depends most of the time on the caller of the API, not on the writter of the API. An API should not use checked exceptions as only unchecked exceptions allows to choose to either catch or ignore an exception.
You're correct.
Unchecked exceptions are used to let the system fail fast which is a good thing. You should clearly state what is your method expecting in order to work properly. This way you can validate the input only once.
For instance:
/**
* #params operation - The operation to execute.
* #throws IllegalArgumentException if the operation is "exit"
*/
public final void execute( String operation ) {
if( "exit".equals(operation)){
throw new IllegalArgumentException("I told you not to...");
}
this.operation = operation;
.....
}
private void secretCode(){
// we perform the operation.
// at this point the opreation was validated already.
// so we don't worry that operation is "exit"
.....
}
Just to put an example. The point is, if the system fails fast, then you'll know where and why it did fail. You'll get an stacktrace like:
IllegalArgumentException: I told you not to use "exit"
at some.package.AClass.execute(Aclass.java:5)
at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
ar ......
And you'll know what happened. The OtherClass in the "delegateTheWork" method ( at line 4569 ) called your class with the "exit" value, even when it shouldn't etc.
Otherwise you would have to sprinkle validations all over your code and that's error prone. Plus, sometimes it is hard to track what went wrong and you may expect hours of frustrating debugging
Same thing happens with NullPointerExceptions. If you have a 700 lines class with some 15 methods, that uses 30 attributes and none of them can be null, instead of validating in each of those methods for nullability you could make all those attributes read-only and validate them in the constructor or factory method.
public static MyClass createInstane( Object data1, Object data2 /* etc */ ){
if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }
}
// the rest of the methods don't validate data1 anymore.
public void method1(){ // don't worry, nothing is null
....
}
public void method2(){ // don't worry, nothing is null
....
}
public void method3(){ // don't worry, nothing is null
....
}
Checked exceptions Are useful when the programmer ( you or your co-workers ) did everything right, validated the input, ran tests, and all the code is perfect, but the code connects to a third party webservice that may be down ( or a file you were using was deleted by another external process etc ) . The webservice may even be validate before the connection is attempted, but during the data transfer something went wrong.
In that scenario there is nothing that you or your co-workers can do to help it. But still you have to do something and not let the application just die and disappear in the eyes of the user. You use a checked exception for that and handle the exception, what can you do when that happens?, most of the time , just to attempt to log the error, probably save your work ( the app work ) and present a message to the user. ( The site blabla is down, please retry later etc. )
If the checked exception are overused ( by adding the "throw Exception" in the all the methods signatures ) , then your code will become very fragile, because everyone will ignore that exception ( because is too general ) and the quality of code will be seriously compromised.
If you overuse unchecked exception something similar will happen. The users of that code don't know if something may go wrong an a lot of try{...}catch( Throwable t ) will appear.
Here is my 'final rule of thumb'.
I use:
unchecked exception within the code of my method for a failure due to the caller (that involves an explicit and complete documentation)
checked exception for a failure due to the callee that I need to make explicit to anyone wanting to use my code
Compare to the previous answer, this is a clear rationale (upon which one can agree or disagree) for the use of one or the other (or both) kind of exceptions.
For both of those exceptions, I will create my own unchecked and checked Exception for my application (a good practice, as mentionned here), except for very common unchecked exception (like NullPointerException)
So for instance, the goal of this particular function below is to make (or get if already exist) an object,
meaning:
the container of the object to make/get MUST exist (responsibility of the CALLER
=> unchecked exception, AND clear javadoc comment for this called function)
the other parameters can not be null
(choice of the coder to put that on the CALLER: the coder will not check for null parameter but the coder DOES DOCUMENT IT)
the result CAN NOT BE NULL
(responsibility and choice of the code of the callee, choice which will be of great interest for the caller
=> checked exception because every callers MUST take a decision if the object can not be created/found, and that decision must be enforced at the compilation time: they can not use this function without having to deal with this possibility, meaning with this checked exception).
Example:
/**
* Build a folder. <br />
* Folder located under a Parent Folder (either RootFolder or an existing Folder)
* #param aFolderName name of folder
* #param aPVob project vob containing folder (MUST NOT BE NULL)
* #param aParent parent folder containing folder
* (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
* #param aComment comment for folder (MUST NOT BE NULL)
* #return a new folder or an existing one
* #throws CCException if any problems occurs during folder creation
* #throws AssertionFailedException if aParent is not in the same PVob
* #throws NullPointerException if aPVob or aParent or aComment is null
*/
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
final IPVob aPVob, final Comment aComment) throws CCException {
Folder aFolderRes = null;
if (aPVob.equals(aParent.getPVob() == false) {
// UNCHECKED EXCEPTION because the caller failed to live up
// to the documented entry criteria for this function
Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }
final String ctcmd = "mkfolder " + aComment.getCommentOption() +
" -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);
final Status st = getCleartool().executeCmd(ctcmd);
if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
aFolderRes = Folder.getFolder(aFolderName, aPVob);
}
else {
// CHECKED EXCEPTION because the callee failed to respect his contract
throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
}
return aFolderRes;
}
It's not just a matter of the ability to recover from the exception. What matter most, in my opinion, is whether the caller is interested in catching the exception or not.
If you write a library to be used elsewhere, or a lower-level layer in your application, ask yourself if the caller is interested in catching (knowing about) your exception. If he is not, then use an unchecked exception, so you don't burden him unnecessarily.
This is the philosophy used by many frameworks. Spring and hibernate, in particularly, come to mind - they convert known checked exception to unchecked exception precisely because checked exceptions are overused in Java. One example that I can think of is the JSONException from json.org, which is a checked exception and is mostly annoying - it should be unchecked, but the developer simply haven't thought it through.
By the way, most of the time the caller's interest in the exception is directly correlated to the ability to recover from the exception, but that is not always the case.
Here is a very simple solution to your Checked/Unchecked dilemma.
Rule 1: Think of a Unchecked Exception as a testable condition before code executes.
for example…
x.doSomething(); // the code throws a NullPointerException
where x is null...
…the code should possibly have the following…
if (x==null)
{
//do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
x = new X();
}
x.doSomething();
Rule 2: Think of a Checked Exception as an un-testable condition that may occur while the code executes.
Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
…in the example above, the URL (google.com) may be unavailable to due the DNS server being down. Even at the instant the DNS server was working and resolved the ‘google.com’ name to an IP address, if the connection is made to google.com, at anytime afterword, the network could go down. You simply can not test the network all the time before reading and writing to streams.
There are times where the code simply must execute before we can know if there is a problem. By forcing developers to write their code in such a way to force them to handle these situations via Checked Exception, I have to tip my hat to the creator of Java that invented this concept.
In general, almost all the APIs in Java follow the 2 rules above. If you try to write to a file, the disk could fill up before completing the write. It is possible that other processes had caused the disk to become full. There is simply no way to test for this situation. For those who interact with hardware where at any time, using the hardware can fail, Checked Exceptions seem to be an elegant solution to this problem.
There is a gray area to this. In the event that many tests are needed (a mind blowing if statement with lots of && and ||), the exception thrown will be a CheckedException simply because it’s too much of a pain to get right — you simply can’t say this problem is a programming error. If there are much less than 10 tests (e.g. ‘if (x == null)’), then the programmer error should be a UncheckedException.
Things get interesting when dealing with language interpreters. According to the rules above, should a Syntax Error be considered a Checked or Unchecked Exception? I would argue that if the syntax of the language can be tested before it gets executed, it should be an UncheckedException. If the language can not be tested — similar to how assembly code runs on a personal computer, then the Syntax Error should be a Checked Exception.
The 2 rules above will probably remove 90% of your concern over which to choose from. To summarize the rules, follow this pattern…
1) if the code to be execute can be tested before it’s executed for it to run correctly and if an Exception occurs — a.k.a. a programmer error, the Exception should be an UncheckedException (a subclass of RuntimeException).
2) if the code to be executed can not be tested before it’s executed for it to run correctly, the Exception should be a Checked Exception (a subclass of Exception).
You can call it a checked or unchecked exception; however, both types of exception can be caught by the programmer, so the best answer is: write all of your exceptions as unchecked and document them. That way the developer who uses your API can choose whether he or she wants to catch that exception and do something. Checked exceptions are a complete waste of everyone's time and it makes your code a shocking nightmare to look at. Proper unit testing will then bring up any exceptions that you may have to catch and do something with.
Checked Exception:
If client can recover from an exception and would like to continue, use checked exception.
Unchecked Exception:
If a client can't do any thing after the exception, then raise unchecked exception.
Example: If you are expected to do arithmetic operation in a method A() and based on the output from A(), you have to another operation. If the output is null from method A() which you are not expecting during the run time, then you are expected to throw Null pointer Exception which is Run time exception.
Refer here
Here is I want to share my opinion I have after many years of development experience:
Checked exception. This is a part of business use case or call flow, this is a part of application logic we expect or not expect. For example connection rejected, condition is not satisfied etc. We need to handle it and show corresponding message to user with instructions what happened and what to do next (try again later etc).
I usually call it post-processing exception or "user" exception.
Unchecked exception. This is a part of programming exception, some mistake in software code programming (bug, defect) and reflects a way how programmers must use API as per documentation. If an external lib/framework doc says it expects to get data in some range and non null, because NPE or IllegalArgumentException will be thrown, programmer should expect it and use API correctly as per documentation. Otherwise the exception will be thrown.
I usually call it pre-processing exception or "validation" exception.
By target audience. Now let's talk about target audience or group of people the exceptions have been designed (as per my opinion):
Checked exception. Target audience is users/clients.
Unchecked exception. Target audience is developers. By other words unchecked exception are designed for developers only.
By application development lifecycle phase.
Checked exception is designed to exist during whole production lifecycle as normal and expected mechanism an application handles exceptional cases.
Unchecked exception is designed to exist only during application development/testing lifecycle, all of them should be fixed during that time and should not be thrown when an application is running on production already.
The reason why frameworks usually use unchecked exceptions (Spring for example) is that framework cannot determine the business logic of your application, this is up to developers to catch then and design own logic.
We have to distinguish these two types of exception based on whether it is programmer error or not.
If an error is a programmer error, it must be an Unchecked Exception. For example:
SQLException/IOException/NullPointerException. These exceptions are
programming errors. They should be handled by programmer. While in
JDBC API, SQLException is Checked Exception, In Spring JDBCTemplate
it is an Unchecked Exception.Programmer doesn't worry about
SqlException, when use Spring.
If an error is not a programmer error and the reason is coming from external, it must be a Checked Exception. For example: if the
file is deleted or file permission is changed by someone else, It
should be recovered.
FileNotFoundException is good example to understand subtle differences. FileNotFoundException is thrown in case file is not found. There are two reason for this exception. If the file path is defined by developer or taking from end user via GUI it should be an Unchecked Exception. If the file is deleted by someone else, it should be a Checked Exception.
Checked Exception can be handled in two ways. These are using try-catch or propagate the exception. In case of propagation of exception, all methods in call stack will be tightly coupled because of exception handling. That's why, we have to use Checked Exception carefully.
In case you develop an layered enterprise system, you have to choose mostly unchecked exception to throw, but don't forget to use checked exception for the case you cannot do anything.
I agree with the preference for unchecked exceptions as a rule, especially when designing an API. The caller can always choose to catch a documented, unchecked exception. You're just not needlessly forcing the caller to.
I find checked exceptions useful at the lower-level, as implementation detail. It often seems like a better flow of control mechanism than having to manage a specified error "return code". It can sometimes help see the impact of an idea for a low level code change too... declare a checked exception downstream and see who would need to adjust. This last point doesn't apply if there are a lot of generic: catch(Exception e) or throws Exception which is usually not too well-thought out anyway.
Checked exceptions are useful for recoverable cases where you want to provide information to the caller (i.e. insufficient permissions, file not found, etc).
Unchecked exceptions are used rarely, if at all, for informing the user or programmer of serious errors or unexpected conditions during run-time. Don't throw them if you're writing code or libraries that will be used by others, as they may not be expecting your software to throw unchecked exceptions since the compiler doesn't force them to be caught or declared.
Whnever an exception is less likely expected, and we can proceed even after catching that, and we can not do anything to avoid that exception then we can use checked exception.
Whenever we want to do something meaningful when a particular exceptions happens and when that exception is expected but not certain, then we can use checked exception.
Whenever exception navigating in different layers, we don't need to catch it in every layer, in that case, we can use runtime exception or wrap exception as unchecked exception.
Runtime exception is used when exception most likely to be happened, there is no way of going further and nothing can be recoverable. So in this case we can take precautions with respect to that exception. EX: NUllPointerException, ArrayOutofBoundsException. These are more likely to happen. In this scenario, we can take precautions while coding to avoid such exception. Otherwise we will have to write try catch blocks every where.
More general exceptions can be made Unchecked, less general are checked.
I think we can think about exeptions from several questions:
why does exeption happen? What can we do when it happens
by mistake, a bug. such as a method of null object is called.
String name = null;
... // some logics
System.out.print(name.length()); // name is still null here
This kind of exception should be fixed during test. Otherwise, it breaks the production, and you got a very high bug which needs to be fixed immediately. This kind of exceptions do not need be checked.
by input from external, you cannot control or trust the output of external service.
String name = ExternalService.getName(); // return null
System.out.print(name.length()); // name is null here
Here, you may need to check whether the name is null if you want to continue when it is null, otherwise, you can let it alone and it will stop here and give the caller the runtime exception.
This kind of exceptions do not need be checked.
by runtime exception from external, you cannot control or trust the external service.
Here, you may need to catch all exceptions from ExternalService if you want to continue when it happens, otherwise, you can let it alone and it will stop here and give the caller the runtime exception.
by checked exception from external, you cannot control or trust the external service.
Here, you may need to catch all exceptions from ExternalService if you want to continue when it happens, otherwise, you can let it alone and it will stop here and give the caller the runtime exception.
In this case, do we need to know what kind of exception happened in ExternalService? It depends:
if you can handle some kinds of exceptions, you need to catch them and process. For others, bubble them.
if you need log or response to user the specific execption, you can catch them. For others, bubble them.
I think when declaring Application Exception it should be Unchecked Exception i.e., subclass of RuntimeException.
The reason is it will not clutter application code with try-catch and throws declaration on method. If your application is using Java Api which throws checked exceptions that anyways need to be handle. For other cases, the application can throw unchecked exception. If the application caller still needs to handle unchecked exception, it can be done.
The rule I use is: never use unchecked exceptions! (or when you don't see any way around it)
From the point of view of the developer using your library or the end-user using your library/application it really sucks to be confronted with an application that crashes due to an uncought exception. And counting on a catch-all is no good either.
This way the end user can still be presented with an error message, instead of the application completely disappearing.