How do I prevent an exception from stopping my program? - java

I'm using a thread to run a half of an application, and the other half is running by itself. I did this so that the one part fetching the data (because I'm running an infinite loop) would not stop the other part from doing it's job. Now I was wondering: if an exception occurred on one part it would block the some of the other part because they are dependent on each other.
So my question is, how could I prevent an exception from stopping my whole program and make it continue do things?

Try-catch or throw an exception. If neither of those sound familiar, I would look them up.
an example of try-catch
try
{
//your code that may throw exception
}catch(TheException e){
e.printStackTrace(); // or however you handle exceptions
}
good resource for throwing exceptions: https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html

Throwing an exception from one thread generally will not impact the runtime of the others. Threads are kind of off in their own little world in that regard.
That said, if two threads are sharing some state (whether directly through the heap or indirectly through a database or something like that) and one thread leaves the application's data in an unstable/corrupted state because it bombed out, that could obviously impact the behavior of the other threads, making them do further "bad stuff." You will want to prevent this whenever possible; best way to do it is to document your exceptions as best you can and to catch and handle them when thrown, and to back your logic with robust unit tests.

You can create a boolean variable maybe called running so that while your while loop is working fine, this variable will be true. Immediately an exception is caught, the variable becomes false. Your main task can then check the variable anytime it wants to use the shared data. If the variable is true, read the data; else, do something else like restarting the thread depending on the type of exception caught.
Remember, in order to make the variable false, you will need to include its update in your catch clause.
There are better and more complex methods out there like the use of ExecutorService.

Related

How to deal with: Call to 'Thread.sleep()' in a loop, probably busy-waiting

Guys how to deal with such code and warning?
private void listenOnLogForResult() {
String logs = "";
int timeCounter = 1;
while (logs.isEmpty()) {
try {
timeCounter++;
Thread.sleep(2000); // Wait 2 seconds
} catch (InterruptedException e) {
log.error(e.getLocalizedMessage(), e);
}
if (timeCounter < 30) {
logs = checkLogs()
} else {
logs = "Time out";
}
}
}
I need to pause current thread for 2 seconds to wait file to be filled, but my Intelij Rise an issue here.
And also I am getting error from sonar:
SonarLint: Either re-interrupt this method or rethrow the "InterruptedException".
I've tried already with many ExecutorService, but it is always run in seperate thread, and I need to pause current one.
Please help..
The busy-waiting warning
This is a warning coming from intellij that is dubious, in the sense that what you're doing is often just straight up required. In other words, it is detecting a pattern that is overused, but whose usage cannot be reduced to 0. So, likely the right solution is to just tell intellij to shut up about it here.
The problem it is looking at is not that Thread.sleep. That is not the problem. However, intellij's detector of this pattern needs it to find this case, but it is not what it is complaining about, which might be a little hard to wrap your head around.
What IntelliJ is worried about, is that you're wasting cycles continually rechecking log.isEmpty() for no reason. It has a problem with the while aspect of this code, not the sleep. It would prefer to see code where you invoke some sort of logs.poll() method which will just wait until it is actively woken up by the act of new logs appearing.
If this is all running within a single java process, then you can indeed rewrite this entire system (which includes rewrites to whatever log is here, and a complete re-imagining of the checkLogs() method: Instead of going out and checking, whatever is making logs needs to wake up this code instead.
If it's not, it is likely that you need to tell intellij to shut it: What you are doing is unavoidable without a complete systems redesign.
The re-interrupt warning
You have some deplorable exception handling here.
Your exception handling in general
Do not write catch blocks that log something and keep moving. This is really bad error handling: The system's variables and fields are now in an unknown state (you just caught and logged some stuff: Surely that means you have no idea what conditions have occurred to cause this line of execution to happen!), and yet code will move right along. It is extremely likely that 'catch exceptions and just keep going' style code results in more exceptions down the line: Generally, code that operates on unknown state is going to crash and burn sooner rather than later.
Then, if that crash-and-burn is dealt with in the same fashion (catch it, log it, keep going), then you get another crash-and-burn. You end up with code that will, upon hitting a problem, print 186 exceptions to the log and they are all utterly irrelevant except the first one. That's bad yuyu.
You're also making it completely impossible for calling code to recover. The point of exceptions is that they need to bubble upwards endlessly: Either the exception is caught by code that actually knows how to deal with the problem (and logging it is not dealing with it!), which you are making impossible, or, the code exception should bubble up all the way to the entry-point handler which is the right place to log the error and abort the entry-point handler.
An entry-point handler is a generic module or application runner; out of the box, the code baked into java.exe itself that ends up invoking your psv main() method is the most obvious 'entry point runner', but there's more: Web frameworks will eventually invoke some code of yours that is supposed to handle a web request: That code of yours is analogous to psv main(): It is the entry-point, and the code in the web framework that invokes it, is the entry-point runner.
Entry-point runners have a good reason to catch (Throwable t), and to spend their catch block primarily logging it, though they should generally log a lot more than just the exception (a web handler should for example log the request details, such as which HTTP params were sent and which path request it was, maybe the headers, etc). Any other code should never do this, though.
If you have no idea what to do and don't want to think about what that exception might mean, the correct 'whatever, just compile already javac' code strategy is to add the exception type to your throws line. If that is not feasible, the right code in the catch block is:
} catch (ExceptionIDoNotWantToThinkAboutRightNow e) {
throw new RuntimeException("Uncaught", e);
}
This will ensure that code will not just merrily continue onwards, operating on unknown state, and will ensure you get complete details in logs, and ensures that calling code can catch and deal with it if it can, and ensures that any custom logging info such as the HTTP request details get a chance to make it to the logs. Win-win-win-win.
This case in particular: What does InterruptedEx mean?
When some code running in that java process invokes yourThread.interrupt(), that is how InterruptedException can happen, and it cannot possibly happen in any other way. If the user hits CTRL+C, or goes into task manager and clicks 'end process', or if your android phone decides it is time for your app to get out as the memory is needed for something else - none of those cases can possibly result in InterruptedExceptions. Your threads just get killed midstep by java (if you want to act on shutdowns, use Runtime.getRuntime().addShutdownHook). The only way is for some code to call .interrupt(), and nothing in the core libs is going to do that. Thus, InterruptedException means whatever you think 'call .interrupt() on this thread' means. It is up to you.
The most common definition is effectively 'I ask you to stop': Just shut down the thread nicely. Generally it is bad to try to shut down threads nicely if you want to exit the entire VM (just invoke System.shutdown - you already need to deal with users hitting CTRL+C, why write shutdown code twice in different ways?) - but sometimes you just want one thread to stop. So, usually the best code to put in a catch (InterruptedException e) block is just return; and nothing else. Don't log anything: The 'interrupt' is intentional: You wrote it. Most likely that is nowhere in your code base and the InterruptedException is moot: It won't ever happen.
In your specific code, what happens if your code decides to stop the logger thread is that the logger thread will log something to the error logs, and will then shortcut its 2 second wait period to immediately check the logs, and then just keeps going. That sounds completely useless.
But, it means whatever you want it to. If you want an ability for e.g. the user to hit a 'force check the logs right now' button, then you can define that interrupting the logging thread just shortcuts the 2 seconds (but then just have an empty catch block with a comment explaining that this is how you designed it, obviously don't log it). If you ALSO want a button to 'stop the logging thread', have an AtomicBoolean that tracks 'running' state: When the 'stop log-refreshes' button is hit, set the AB to 'false' and then interrupt the thread: Then the code you pasted needs to check the AB and return; to close the thread if it is false.
fun sleep(timeMillis: Long) {
val currentTimeMillis = System.currentTimeMillis()
while (true) {
if (System.currentTimeMillis() - currentTimeMillis >= timeMillis) {
break
}
}
}
and use this in your method(It's code by koltin,you should trans to java)

What's the point of try/catch blocks to catch Exceptions?

Why do we need try/catch blocks to catch any Exceptions that may arise in our code? Once we run the program and lets assume we have a RuntimeException, won't the program just automatically abort and give us the error anyways? Why do we need try/catch blocks to do this for us then?
It's just good practice. If the user is given with something like "IndexOutOfrangeexception" what is he going to do with it? Just assume everything is OK and he should start over? What in case of doing some work with the software - is the work lost? What happened?
Put yourself in such stuation: you downloaded some software, you start using it as normal, and you are happy with it. But one day you run program and it gives you error and program dies - do you know what happened? No. Do you know what went wrong? No. Do you know how to prevent it and start using software so the error doesn't occur again? No.
YOU ARE THE DEVELOPER, you know what happens inside. So for example, you are trying to save data in database, but somehow connection got lost and you will likely get an exception - in catch block you can catch this exception and give the user MEANINGFUL information, e.g. "The connection with database is lost. Check the network. Your data is not saved and you should do the work again." - isn't that better than just some "SQL exception" alongside with the stacktrace?
Additionally, catch/finally blocks are here to clean-up potential mess, for example you are writing some content to a file, but it only makes sense, when you can write all data, not just the part of it. So in catch block you could erase incomplete data, so the file is not corrupted for example.
Also, when working with unanaged resources, you should use finally block to clean them up (for example DB/netowrk connections).
Think about the scenarios when working with a live website or application. You wouldn't want the user to see a blank screen or a screen full of error trace code. In such scenarios, potential areas of exception can be handled to show a message to the user that makes sense "sorry, you are exceeding more than 10 items in your cart etc ", "you do not have sufficient amount in your account", "username cannot have symbols ", "out service us un-operational right now please come back later".
Try catch is used to handle the such error conditions gracefully. You can enclose a code set into try and its catch would be responsible to handle it. Handling may depend on your use case but your java program wont terminate.
Abrupt termination of program doesn't let you know the actual reason of failure.
Because if you don't catch an exception the entire method execution will simply stop, including the execution of any calling methods. So if a method A needs something of method B and calls it, and method B throws an exception, then that exception will cause method A to stop execution. If method A was being called by another method that method will stop execution too if it doesn't catch the exception from method B. So an exception will work its way up the method calling chain until it is catched by a method or gets to the most upper/outer method.
Also, any exception that is not inheriting from the RuntimeException class or is not an instance of the RuntimeException class itself must either be catched or else your code will not compile. If you really don't want to handle this kind of exception then you can also let the calling method receive the exception by adding throws Exception to your method signature. A runtimeexception extending class is called an unchecked exception, you don't have to include that in the method or in the method signature. Anything extending Exception but not RuntimeException is called a checked exception and should either be catched or put in the method signature by using throws keyword.
EDIT: Here you can find a good explanation too Does every exception have an required try-catch?
Other than examples users given, also, on Android for hardware specific operations, camera for instance, can throw RuntimeExceptions even you do everything right, it does it a lot with camera based on devices. I set ISO for instance camera and it's not a crucial for my app to work but i don't want my app to crash so i throw an exception and show a warning to user so app continue to work.

Using try/catch for preventing app from crashes

I have been working on an Android app which uses try/catch frequently to prevent it from crashing even on places where there is no need. For example,
A view in xml layout with id = toolbar is referenced like:
// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}
This approach is used throughout the app. The stack trace is not printed and it's really hard to find what went wrong. The app closes suddenly without printing any stack trace.
I asked my senior to explain it to me and he said,
This is for preventing crashing in production.
I totally disagree with it. To me this is not the way to prevent apps from crashes. It shows that developer doesn't know what he/she is doing and is in doubt.
Is this the approach being used in industry to prevent enterprise apps from crashes?
If try/catch is really, really our need then is it possible to attach an exception handler with UI thread or other threads and catch everything there? That will be a better approach if possible.
Yes, empty try/catch is bad and even if we print stack trace or log exception to server, wrapping blocks of code in try/catch randomly across all the app doesn't make sense to me e.g. when every function is enclosed in a try/catch.
UPDATE
As this question has got a lot of attention and some people have misinterpreted the question (perhaps because I haven't phrased it clearly) I am going to rephrase it.
Here is what developers are doing here
A function is written and tested, it can be a small function which just initializes views or a complex one, after testing it is wrapped around try/catch block. Even for function which will never throw any exception.
This practice is used throughout the application. Sometime stack trace is printed and sometime just a debug log with some random error message. This error message differ from developer to developer.
With this approach, app does not crash but behavior of the app becomes undetermined. Even sometime it is hard to follow what went wrong.
The real question I have been asking was; Is it the practice being following in the industry for preventing the enterprise applications from crashes? and I am not asking about empty try/catch. Is it like, users love application which do not crash than applications which behave unexpectedly? Because it really boils down to either crash it or present the user with a blank screen or the behaviour user is unaware of.
I am posting a few snippets from the real code here
private void makeRequestForForgetPassword() {
try {
HashMap<String, Object> params = new HashMap<>();
String email= CurrentUserData.msisdn;
params.put("email", "blabla");
params.put("new_password", password);
NetworkProcess networkProcessForgetStep = new NetworkProcess(
serviceCallListenerForgotPasswordStep, ForgotPassword.this);
networkProcessForgetStep.serviceProcessing(params,
Constants.API_FORGOT_PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
}
private void languagePopUpDialog(View view) {
try {
PopupWindow popupwindow_obj = popupDisplay();
popupwindow_obj.showAsDropDown(view, -50, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
void reloadActivity() {
try {
onCreateProcess();
} catch (Exception e) {
}
}
It is not duplicate of Android exception handling best
practices, there OP is trying to catch exception for a different
purpose than this question.
Of course, there are always exceptions to rules, but if you need a rule of thumb - then you are correct; empty catch blocks are "absolutely" bad practice.
Let's have a closer look, first starting with your specific example:
try {
View view = findViewById(R.id.toolbar);
}
catch(Exception e) { }
So, a reference to something is created; and when that fails ... it doesn't matter; because that reference isn't used in the first place! The above code is absolutely useless line noise. Or does the person who wrote that code initially assume that a second, similar call would magically no longer throw an exception?!
Maybe this was meant to look like:
try {
View view = findViewById(R.id.toolbar);
... and now do something with that view variable ...
}
catch(Exception e) { }
But again, what does this help?! Exceptions exist to communicate respectively propagate error situations within your code. Ignoring errors is rarely a good idea. Actually, an exception can be treated in ways like:
You give feedback to the user; (like: "the value you entered is not a string, try again"); or to engage in more complex error handling
Maybe the problem is somehow expected and can be mitigated (for example by giving a "default" answer when some "remote search" failed)
...
Long story short: the minimum thing that you do with an exception is to log/trace it; so that when you come in later debugging some problem you understand "OK, at this point in time that exception happened".
And as others have pointed out: you also avoid catching for Exception in general (well, depending on the layer: there might be good reasons to have some catch for Exception, and even some kinds of Errors at the highest level, to make sure that nothing gets lost; ever).
Finally, let's quote Ward Cunningham:
You know you are working with clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem.
Let that sink in and meditate about it. Clean code does not surprise you. The example you are showing to us surprises everybody looking at.
Update, regarding the update that the OP asks about
try {
do something
}
catch(Exception e) {
print stacktrace
}
Same answer: doing that "all over the place" is also bad practice. Because this code is also surprising the reader.
The above:
Prints error information somewhere. It is not at all guaranteed that this "somewhere" resembles a reasonable destination. To the contrary. Example: within the application I am working with, such calls would magically appear in our trace buffers. Depending on context, our application might pump tons and tons of data into those buffers sometimes; making those buffer prune every few seconds. So "just printing errors" often translates to: "simply loosing all such error information".
Then: you don't do try/catch because you can. You do it because you understand what your code is doing; and you know: I better have a try/catch here to do the right thing (see the first parts of my answer again).
So, using try/catch as "pattern" like you are showing; is as said: still not a good idea. And yes, it prevents crashes; but leads to all kind of "undefined" behavior. You know, when you just catch an exception instead of properly dealing with it; you open a can of worms; because you might run into myriads of follow-on errors that you later don't understand. Because you consumed the "root cause" event earlier on; printed it somewhere; and that somewhere is now gone.
From the Android documentation:
Let's entitle it as -
Don't Catch Generic Exception
It can also be tempting to be lazy when catching exceptions and do something like this:
try {
someComplicatedIOFunction(); // may throw IOException
someComplicatedParsingFunction(); // may throw ParsingException
someComplicatedSecurityFunction(); // may throw SecurityException
// phew, made it all the way
} catch (Exception e) { // I'll just catch all exceptions
handleError(); // with one generic handler!
}
In almost all cases it is inappropriate to catch generic Exception or Throwable (preferably not Throwable because it includes Error exceptions). It is very dangerous because it means that Exceptions you never expected (including RuntimeExceptions like ClassCastException) get caught in application-level error handling.
It obscures the failure handling properties of your code, meaning if someone adds a new type of Exception in the code you're calling, the compiler won't help you realize you need to handle the error differently.
Alternatives to catching generic Exception:
Catch each exception separately as separate catch blocks after a single try. This can be awkward but is still preferable to catching all Exceptions.
Edit by author: This one is my choice. Beware repeating too much code in the catch blocks. If you are using Java 7 or above, use multi-catch to avoid repeating the same catch block.
Refactor your code to have more fine-grained error handling, with multiple try blocks. Split up the IO from the parsing, handle errors separately in each case.
Re-throw the exception. Many times you don't need to catch the exception at this level anyway, just let the method throw it.
In most cases you shouldn't be handling different types of exception the same way.
Formatting / paragraphing slightly modified from the source for this answer.
P.S. Don't be afraid of Exceptions!! They are friends!!!
I would put this as a comment to some other answer, but I don't have the reputation for that yet.
You are correct in saying that it's bad practice, in fact what you posted shows different types of bad practice in regards to exceptions.
Lack of error handling
Generic Catch
No intentional exceptions
Blanket Try/catch
I'll try to explain all of those via this example.
try {
User user = loadUserFromWeb();
if(user.getCountry().equals("us")) {
enableExtraFields();
}
fillFields(user);
} catch (Exception e) {
}
This can fail in several ways that should be handled differently.
The fields will not be filled, so the user is presented with an empty screen and then... what? Nothing - lack of error handling.
There's no distinction between different types of errors, e.g. Internet problems or problems with the server itself (outage, broken request, corrupted transmission, ...) - Generic catch.
You can not use exceptions for your own purposes because the current system interferes with that. - No intentional exceptions
Unessential and unexpected errors (e.g. null.equals(...)) can cause essential code not to execute. - Blanket try/catch
Solutions
(1) First of all, failing silently is not a good thing. If there's a failure, the app won't work. Instead there should be an attempt to resolve the problem or a display a warning, for example "Could not load user data, maybe you're not connected to the Internet?". If the app is not doing what it's supposed to, that's way more frustrating for a user than if it just closes itself.
(4) If the User is incomplete, e.g. the country is not known and returns null. The equals method will create a NullPointerException. If that NPE is just thrown and caught like above, the fillFields(user) method will not be called, even though it could still be executed without problems. You could prevent this by including null checks, changing execution order, or adjusting the try/catch scope. (Or you could do save coding like this: "us".equals(user.getCountry()), but I had to provide an example). Of course any other exception will also prevent fillFields() from being executed, but if there's no user, you probably don't want it executed anyway.
(1, 2, 3)Loading from web often throws a variety of exceptions, from IOException to HttpMessageNotReadable exception to even just returning. Could be that the user isn't connected to the internet, could be that there was a change to a backend server or it is down, but you don't know because you do catch(Exception) - instead you should catch specific exceptions. You can even catch several of them like this
try{
User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist
if(user == null) {
throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used.
}
fillFields(user);
if("us".equals(user.getCountry()) {
enableExtraFields();
}
} catch(NoInternetException e){
displayWarning("Your internet conneciton is down :(");
} catch(ServerNotAvailableException e){
displayWarning("Seems like our server is having trouble, try again later.");
} catch(UserDoesNotExistException e){
startCreateUserActivity();
}
I hope that explains it.
At the very least as a quick fix, what you could do is send an event to your backend with the exception. For example through firebase or crashlytics. That way you can at least see stuff like (hey, the main activity does not load for 80% of our users due to a problem like (4).
It's definitely a bad programming practice.
From the current scenario, if there are hundreds of try catch like this, then you won't even know where the exception occurs without debugging the application, which is a nightmare if your application is in production environment.
But you can include a logger so that you get to know when an exception is throws (and why). It won't change your normal workflow.
...
try {
View view = findViewById(R.id.toolbar);
}catch(Exception e){
logger.log(Level.SEVERE, "an exception was thrown", e);
}
...
This is bad practice. Other answers have said that but I'd think it's important to step back and understand why we have exceptions in the first place.
Every function has a post-condition – a set of things that must all be true after that function executes. For example, a function that reads from a file has the post condition that the data in the file will be read from disk and returned. An exception, then, is thrown when a function has not been able to satisfy one of its post-conditions.
By ignoring an exception from a function (or even effectively ignoring it by simply logging the exception), you're saying that you're ok with that function not actually doing all the work it agreed to do. This seems unlikely – if a function does not run correctly, there is no guarantee that what follows will run at all. And if the rest of your code runs fine whether or not a particular function runs to completion, then one wonders why you have that function in the first place.
[Now there are certain cases where empty catches are ok. For example, logging is something that you might justify wrapping in an empty catch. Your application will probably run fine even if some of the logging can't be written. But those are special cases that you have to work really hard to find in a normal app.]
So the point is, this is bad practice because it doesn't actually keep your app running (the supposed justification for this style). Maybe technically the OS hasn't killed it. But it's unlikely that the app is still running properly after simply ignoring an exception. And in the worst case, it could actually be doing harm (e.g. corrupting user files, etc.).
This is bad for multiple reasons:
What are you doing that findViewById throws an Exception? Fix that (and tell me, because I've never seen this) instead of catching.
Don't catch Exception when you could catch a specific type of exception.
There is this belief that good apps don't crash. That's not true. A good app crashes if it must.
If an app goes into a bad state, it is much better for it to crash than for it to chug along in its unusable state. When one sees an NPE, one shouldn't just stick in a null check and walk away. The better approach is to find out why something is null and either stop it from being null, or (if null ends up being a valid and expected state) check for null. But you have to understand why the issue occurs in the first place.
I have been developing android apps for the past 4-5 years and never used a try catch for view initialisation.
If its a toolbar do like this
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
eg:- To get a TextView from a view(fragment/dialog/any custom view)
TextView textview = (TextView) view.findViewById(R.id.viewId);
TextView textview = (TextView) view.findViewById(R.id.viewId);
instead of this
View view = findViewById(R.id.toolbar);
A view object has minimum reach compared to its real view type.
Note:- May be it crashed because the view was loaded. But adding try catch is a bad practice.
Yes, try/catch is used to prevent app from crashing but You certainly don't need try/catch for fetching a view from XML as depicted in your question.
try/catch is generally used while making any http request, while parsing any String to URL, creating URL connections, etc. and also make sure to print stack trace. Not printing it doesn't make much sense in surrounding it with try/catch.
As said before, general exceptions shouldn't be catched, or at least only in a few central places (usually located in framework/infrastructure code, not application code). If catching general exceptions and logging it, the application should be shut down afterwards, or at the very least user should be informed that application is potentially in a unstable state and data corruption could occur (if user chooses to continue execution). Because this is what might happen if you catch all sort of exceptions (out of memory to name one) and leaving the app in an undefined state.
IMHO it is worse to swallow exceptions and risk data integrity, data loss, or simply leaving the app in an undefined state than letting the app crash and the user knows that something went wrong and can try again. This will also lead to better issues reported (more at the root of the problem), probably fewer different symptoms than if your users start to report all kind of troubles originating from undefined application state.
After a central exception handling/logging/reporting and controlled shutdown is in place, start rewriting exception handling to catch local exceptions as specific as possible. Try to make the try{} block as short as possible.
Let me add my point of view, as a guy working in the corporate mobile development industry for more than a decade. First, some general tips on exceptions, most of them included in answers above:
Exceptions should be used for exceptional, unexpected or uncontrolled situations, not on a regular basis throughout the code.
A programmer must know the portions of code susceptible to throw exceptions and try-catch them, leaving the rest of the code as clean as possible.
Exceptions should not be left silent, as a general rule.
Now, when you are not developing an app for yourself, but for a company or a corporation, it is common to face additional requirements on this topic:
"App crashes show a poor image of the company, so they are not acceptable". Then, careful development should be performed, and catching even improbable exceptions may be an option. If so, this must be done selectively and kept in reasonable limits. And notice that development is not all about lines of code, for instance, an intensive testing process is critical in these cases. However, unexpected behaviour in a corporate app is worse than crashing. So, whenever you catch an exception in your app, you must know what to do, what to show and how the app will behave next. If you cannot control that, better let the app crash.
"Logs and stack traces may dump sensitive information to the console. That might be used for an attacker, so for security reasons they cannot be used in a production environment". This requirement conflicts with the general rule for a developer not to write silent exceptions, so you have to find a way for it. For instance, your app could control the environment, so it uses logs and stack traces in non-production environments, while using cloud-based tools like bugsense, crashlitics or similar for production environments.
So, the short answer is that the code you found it is not a good practice example, since it is hard and costly to maintain without improving the quality of the app.
Another perspective, as someone who writes enterprise software on a daily basis, if an app has an unrecoverable error, I want it to crash. Crashing is desirable. If it crashes, it gets logged. If it crashes more than a few times in a short period of time, I get an e-mail saying that the app is crashing and I can verify that our app and all the web services we consume are still working.
So the question:
Is
try{
someMethod();
}catch(Exception e){}
good practice? No! Here are a few points:
The MOST important thing: This is a bad customer experience. How am I supposed to know when something bad is happening? My customers are trying to use my app and nothing works. They can't check their bank account, pay their bills, whatever my app does. My app is completely useless, but hey, at least it didn't crash! (Part of me believes this "Senior" dev gets brownie points for low crash numbers, so they're gaming the system.)
When I'm doing development and I write bad code, if I'm just catching and swallowing all exceptions at the top layer I have no logging. I have nothing in my console, and my app fails silently. From what I can tell, everything appears to work okay. So I commit the code... Turns out my DAO object was null the whole time, and the customer's payments were never actually updating in the DB. Whoops! But my app didn't crash, so that's a plus.
Playing devil's advocate, let's say I was okay with catching and swallowing every exception. It's extremely easy to write a custom exception handler in Android. If you really just have to catch every exception, you can do it in one place and not pepper try/catch all over your codebase.
Some of the developers I've worked with in the past have thought crashing was bad.
I have to assure them we want our app to crash. No, an unstable app is not okay, but a crash means we did something wrong and we need to fix it. The faster it crashes, the earlier we find it, the easier it is to fix. The only other option I can think of is allowing the user to continue in a broken session, which I equate with pissing off my userbase.
It's bad practice to use catch(Exception e){} because you're essentially ignoring the error. What you probably want to do is something more like:
try {
//run code that could crash here
} catch (Exception e) {
System.out.println(e.getMessage());
}
We pretty use much your same logic. Use try-catch to prevent production apps from crashing.
Exceptions should be NEVER ignored. It is a bad coding practice. The guys maintaining the code will have a really hard time localizing the part of code that raised the exception if they are not logged.
We use Crashlytics to log the exceptions. The code will not crash (but some functionality will be disrupted). But you get the exception log in the dashboard of Fabric/Crashlytics. You can look at these logs and fix the exceptions.
try {
codeThatCouldRaiseError();
} catch (Exception e) {
e.printStackTrace();
Crashlytics.logException(e);
}
While I agree with the other responses, there is one circumstance I have repeatedly encountered where this motif is marginally tolerable. Suppose someone wrote a bit of code for a class as follows:
private int foo=0;
. . .
public int getFoo() throws SomeException { return foo; }
In this circumstance, the 'getFoo()' method cannot fail - there will always be a legitimate value of the private field 'foo' to be returned. Yet someone - probably for pedantic reasons - decided that this method should be declared as potentially throwing an Exception. If you then try to call this method in a context - e.g an event handler - which does not allow an exception to be thrown, you are basically forced to use this construct (even then, I agree that one should at least log the exception just in case). Whenever I have to do this, I always at least add a big fat comment 'THIS CANNOT OCCUR' next to the 'catch' clause.

Why Would you catch Throwable and do nothing but print a stack trace?

I have tried looking for an answer to this on other threads, but so far I have only seen threads that state that catching Throwable is bad. My question is, is there ever a reason why you would WANT to do this and then do nothing in the catch block except print out the stack trace?
I was recently brought onto a project and given the task of cleaning up the error handling of an existing set of classes for a RESTful service. Several of the helper service classes have try/catch blocks that only catch Throwable and print out the stack trace, as shown below:
class MainService {
SubService1 s1;
SubService2 s2;
public doMainService() {
}
}
class SubService1 {
public int findSomething() {
try {
// Do Something
} catch (Throwable t) {
t.printStackTrace();
}
}
}
class SubService2 {
public int findSomethingElse() {
try {
// Do Something
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Is there a case that this is acceptable? Would it be better for the methods to throw Exception and not have the try/catch blocks?
This is almost never a good practice for a variety of well known reasons.
In particular, it doesn't distinguish between checked and unchecked exceptions and errors. More importantly, one of the effects of this code is allowing the application to execute beyond the exception handler which may result in all kinds of strange behavior due to violated invariants. In other words, since the exception caught may be really anything including violated assertions, programming errors, thread interruptions, missing classes, I/O errors, OOM conditions and even library and VM bugs, the program state is practically unpredictable beyond the exception handler.
In some rare situations broad exception handling may make sense. Imagine a server handling multiple independent requests. You may not want to crash due to a problem encountered while serving one of the requests. Since you do not rely on the state left after the exception handler, you can simply print the stack trace and let someone investigate while the server continues serving other requests.
Even in these situations one should carefully consider whether errors, e.g. VirtualMachineError should really be caught.
One reason that I think people do this is just because Java forces you to either surround calls that throw with a try/catch block, or add throws to the method declaration.
If you "know" that you're not going to have an exception occur, then it's kind of a way to prevent it from going up the chain (cause if you do throws, who ever calls your code needs to surround with a try/catch and so on), but if something does occur it'll dump it without crashing.
You might do that if you don't know any other way to get the stack trace and you want to know how you got to your current location. Not a very good reason, but a possible one. This doesn't seem to fit what you're looking at though; you seem to have been given code which doesn't crash but also doesn't do a good job with error handling.
I use it to see exactly where my program is crashing. So basically just for debugging. Also just to see if it's flowing in the way expected.
It is possible that they wanted to see the stack trace without crashing the program.
For example it can be appropriate for code executed by a thread to log exceptions but otherwise do nothing when it is unacceptable for the thread to crash since the next iteration (say where threads are taking items from a queue) may work as expected. This depends on the use case, but for a server you generally want the threads to be bullet proof and log any errors, instead of halting any further processing (but use cases may vary).
Most simplest example we come across in your problem is when it comes to close an input stream.Follwoing is the method declaration in InputStream class.
public void close() throws IOException
Althoug there is a possiblity to throw an exception when we call this method it would be no harm for the program execution.(Since we will not use that InputStream further) In that case we should only log the error and continue the program. But if you find out an exception which change the states of an object and then you must think about recovery code or halt execution.
Never do this (e.printStackTrace()). many IDE's default to it, but its horrible (many apps run with stderr redirected in ways that are not accessible, and thus, never seen). rules of thumb:
if you truly don't care about the exception (never, ever, ever, ever will care), catch it and do nothing with a big comment which says "we really, really don't ever care if this exception gets thrown"
if you never expect an exception to actually be thrown (the interface defines a checked exception, but you know the impl doesn't actually throw it), rethrow the exception as something like new UnsupportedOperationException("this should never happen", t) (that way if/when the underlying impl gets changed you find out about it sooner rather than later)
if you expect that the exception is unlikely, and you usually will not care about it, log it with a proper logging infrastructure (log4j, commons logging, or java.util.logging). that way it will most likely make it somewhere that you can see later if you decide that you actually do care about the exception after all.

In the multi-thread program like producer/consumer, what's the purpose of Swallowing InterruptedException

Some code simply call
catch (InterruptedException ex) {}, why?
This is usually a sign that the developer didn't know how to handle the Exception and thus just ignored it.
This is the sort of bad behaviour that results in some saying checked exceptions are a failed experiment. IMHO Developers should just learn to handle exceptions.
A better way to handle this exception is to either
pass it to the caller. i.e. don't catch it.
call Thread.currentThread().interrupt() so the interrupt is not lost.
If such an exception should be impossible, wrap it in a throw new AssertionError(ex)
That is used in situations where an exception may occur but the response to the exception is the same as normal continuation from the try block. A common example is calling sleep(). (However, that's actually often a bad example because being interrupted often signals that an operation should be abandoned.)
InterruptedException is what's called a checked exception. When added to a method you want to call, it's a way of signifying that you must account for this situation, namely that the time you need to process the results of the call may be pre-empted by another thread in the system.
Assume for the moment that you have 6-7 statements in a try block, and you assume they will run in a more or less atomic fashion. Among those statements is one that relies on thread-aware behavior. If that call is pre-empted, your subsequent statements won't run, and you'll have to handle the consequences.
People have all sorts of reasons for catching this exception but taking no action. I can't think of many good reasons for doing this, unless I can clearly show that being interrupted doesn't create an undesirable side-effect in my code. Given any example piece of code that shows this behavior, I would guess no catch logic was included because a) the programmer had no plan for dealing with it; b) the programmer merely wanted to step past the check so the code compiles.

Categories