I have an app that uses JSoup to connect to a web server, and it works fine. Unfortunately, the said web server isn't very reliable. I get SocketException because of time-out connection quite often. I make the connection in a modified IntentService, and I just simply repeat onHandleIntent(intent) in the catch(Exception e) block.
catch(Exception e){
Log.d(Tag, "in catch Exception block...");
onHandleIntent(intent);
}
Theoretically, this should work. But sometimes, I get stack over flow error, and the app ended quite ungracefully. So, what can I do to make it better?
I want to continue to call onHandleIntent, so, maybe I have to call it in iteration instead of recursively. If you can give me advice on how to implement this iteratively, it would be very helpful. Thanks!
I want to continue to call onHandleIntent, so, maybe I have to call it in iteration instead of recursively.
That is correct. If you handle this recursively, a server that continually times out will inevitably result in a stack overflow.
If you can give me advice on how to implement this iteratively, it would be very helpful. Thanks!
Something like this:
for (int tries = 1; ; tries++) {
Connection conn = null;
try {
// attempt to connect
// do stuff
} catch (SocketException ex) {
if (/* timed out */ && tries < MAX_TRIES) {
continue;
}
// report exception
} finally {
if (conn != null) {
// close it
}
}
break;
}
(Maybe someone can think of a less "clunky" way to write this ...)
Related
In this scenario:
Cursor cursor = dbHandler.fetchEvents();
boolean someBool = true;
do {
someStuff();
variables = things;
otherStuff();
} while (someBool && cursor.moveToNext());
There is a possibility that cursor.moveToNext() could throw a number of exceptions, particularly if my database is closed unexpectedly while I am working with the cursor.
What would be the best way to handle any possible exceptions thrown in the while() evaluation? Currently, the whole thing just crashes. I'd prefer to avoid that. The compiler does not like my efforts to add a try/catch directly into the while() eval, and it's ugly as hell. I'm thinking I need to create a new method that does this:
private boolean moveToNext(cursor) {
boolean result = false;
try {
result = cursor.moveToNext();
} catch (Exception e) {
... error handling ...
}
return result;
}
And then change my eval loop to:
Cursor cursor = dbHandler.fetchEvents();
boolean someBool = true;
do {
someStuff();
variables = things;
otherStuff();
} while (someBool && moveToNext(cursor));
Does anyone have any other suggestions? If so, I'd love to hear them. Thanks!
Put the entire block of code in a try / catch block, and that block should capture when you lose your database connection.
Then you need to reinvestigate the entire block to see what makes sense to clean up, and that will give you the contents of the "catch block" of the try / catch. Once you do that, you'll probably notice further improvements on your real code, which will probably make this example you posted, and the suggestions less relevant as you zero in on what you care about.
This really depends on what you want to happen when you encounter an error. When you get the Exception, should you just skip that iteration of the loop and move on to the next one, or simply stop iterating? Or is the whole loop borked, and you need to tell your user that something went wrong?
If you really care about handling each iteration of the loop separately, then your approach will work fine. Or if you want to just detect whether the entire loop encountered an error or not, then you can wrap the whole thing in a try block:
try {
Cursor cursor = dbHandler.fetchEvents();
boolean someBool = true;
do {
someStuff();
variables = things;
otherStuff();
} while (someBool && cursor.moveToNext());
} catch (Exception e) {
//report to the user that the loop failed
}
You can always move the code in while() to the loop body, no big deal
while(true)
{
...
if( ! someBool )
break;
if( ! cursor.moveNext() )
break;
}
then surround it with whatever code you like.
I have started working with enhanced for loops due to it's best practices and habilities to work with ArrayLists.
My code basically gets an ArrayList that contains links to songs and parses this list downloading the songs. One of the exceptions thrown is the TimeoutException, whitch normally happens when the server is overloaded or there's an instability with the internet connection.
To clarify:
try
{
for(Track track : album.getTracks())
{
songdown.downloadTrack(track, directorio, formataudio);
}
}
catch (TimeoutException te)
{
System.out.println("Timeout!");
}
track is an ArrayList whitch is parsed one by one by the songdown.downloadTrack function. When a download fails, a TimeoutException is raised, but I don't know how to treat this exception in order to delete the file I have generated and restart the for statement from the same track, so that the download can happen again.
While it's an open question how advisable this would be, you'd be better off with an inner loop that retries until successful. Something like this:
for (Track track : album.getTracks()) {
boolean downloaded = false;
while (!downloaded) {
try {
songdown.downloadTrack(track, directorio, formataudio);
downloaded = true;
} catch (TimeoutException te) { /* delete partially downloaded song etc */ }
}
}
You'd likely want a max # of retries within each iteration of the for loop or some other additional checks to avoid infinite looping.
There are surely many valid approaches.
Here's one possibility:
int failureCount = 0;
while (failureCount < maxFailures) {
try {
parseAndDownload(someList);
break;
}
catch (Exception ex) {
failureCount ++;
}
}
Please go through this first. First thing is that the catch block should start once the try block is done.
You can catch the exception in the catch block, and write the code which you want to get executed, when the exception occurs, which in you case is starting over again, and deleting the half downloaded songs.
Here is a snippet example, I think you can solve your problem by following this way
ArrayList<String> a = new ArrayList<String>();
a.add("a");
a.add("w");
a.add("d");
//Iterator<String> i = a.iterator();
for(String s:a){
try{
if(s.equals("w")){
throw new Exception("Hello");
}else{
System.out.println(s);
}
}catch (Exception e) {
continue;
}
}
In this snippet, I have explicitly throw an Exception, when it is thrown the catch block will execute, there i have used the keyword continue. This keyword is designed to tackle these kind of situation.
I have a try-catch block that I wish to break like a switch block but I couldn't find a recommended way of doing it. I'm fetching a lot of data in the try-catch block and wish to stop the fetching in between in case a certain condition is met. Just to get it working for now, I've deliberately forced the code to go into the catch block:
int i=0;
try {
//--do stuff----
if(//-------is condition met?--------//)
i = 1/0; // divide 1 by 0 -- a definite exception
}
catch (Exception e) {//---------do nothing---------//}
Is it safe to do this or should I go for another way?
EDIT:I'm fetching some xml data(actually, a lot). Depending on the internet connection, I need to stop the parsing after sometime(time-out) rather than go through the entire stream. I go through loops but I also make some calculations later. It doesn't make any sense to calculate with incomplete data, so I would prefer to just skip the whole thing.
This code smells of some anti-pattern but without more context we can't prescribe a better design. In general, you should only throw an exception for a truly exceptional condition in the state of your program. You should especially not throw an exception for normal (expected) control flow, instead you should use control flow statements such as loops (using break/continue) and return.
If you do wish to keep this structure (even though you should not) then I suggest explicitly throwing a special exception class to make it clear what you are doing, e.g.:
public static class ConditionMetException extends Exception { }
// ...
try {
// do stuff
if ( /* Is condition met? */ ) {
throw new ConditionMetException();
}
} catch (ConditionMetException cme) { /* Do nothing. */ }
But again, you're likely better off refactoring to use a loop and the built in break command.
Either break or throw will do what you want (and the throw would be preferable, you at least have some traceability as to WTH you're doing.
[edit]
what: try {
System.out.println ("before break");
break what;
} catch (Exception e) {}
}
[/edit]
Throwing an Exception just to break is bad practice.
Would this work for your situation?
Put the code currently inside the try into another method, fetchLotsOfData(). It can still throw IOException or whatever is appropriate.
When you want to stop doing your thing fetching the data, just return. Perhaps returning some true/false or status for the success.
So your final code is something like
int recordsRead = -1; // -1 means failure
try {
recordsRead = fetchLotsOfData();
}
catch (IOException ioe) {
// handle the exception
}
// process what you got...
I'm going to answer the "is is a good idea?" part of the question: No.
It is not a good idea to use exceptions to implement expected flow-of-control. It is possible, but not expected, just as it's possible to make all your variables Strings and implement all your data structures in arrays.
Try-blocks are for creating a scope boundary that has certain guarantees at termination (the catch and finally behavior). A code maintainer seeing:
try{ ... }catch(Exception x){}
would very strongly tend to either rethrow x (perhaps wrapped) or eliminate the block entirely.
Try-blocks are not about what's inside their scope. That's what standard looping constructs and, better, functions are for. Your question simply goes away if you put your scope in a function:
RetVal doStuff(Arg arg){
//--do stuff----
if(//-------is condition met?--------//)
return myResult;
}
It is not the try-catch that you should worry about breaking out of. From what I can tell, you are looking to do something along the lines of:
try
{
// do thing 1
// do thing 2
if (!done)
{
// do thing 3
// do thing 4
if (still not done)
{
// do thing 5
}
}
} catch (Exception e)
{
}
If that is what you are trying to do, then that is probably how you should do it (instead of trying to escape from the try-catch). The other way is to shrink your try-catch blocks to surround each task individually.
If you provide more context to your question then it may be possible to provide a better answer.
Just put the rest of the fetching into an if block with the inverse condition:
//--do stuff----
if (!shouldStop) {
// continue doing stuff
}
Looking by your code
int i=0;
try {
//--do stuff----
if(//-------is condition met?--------//)
i = 1/0; // divide 1 by 0 -- a definite exception
}
catch (Exception e) {//---------do nothing---------//}
if the condition is not met? then you dont need to worry about using break, and
if the condition is met, there will be definitely an exception, and it is handled in catch(although you are not doing anything)
If there is no other way you can use a block label
load:{
if(test)//skip the remaining load block
break load;
}
Otherwise you could refactor the loading code into a different method and return early.
Do not use exceptions for non-exception error handling. This is likely a named anti-pattern. If so, I don't know the name.
Here is an example of breaking out of a loop when an exception is thrown and not using exception handling to perform non-exception error handling:
try
{
while (... whatever ...)
{
... do something that might throw a BlammoException.
}
}
catch (BlammoException exception)
{
... handle the exception.
}
Just throw whichever exception you want caught...
boolean stopLoop = false;
while (!stopLoop) {
try {
int key = Integer.parseInt(userInput);
if (key > cutOff) throw new NumberFormatException();//<--like this
else {
System.out.println("Good job, your number didn't suck");
//do some stuff...
stopLoop = true;//<--End loop after some stuff
//some more stuff, or..
if(nomorestuff)break;//<--exit loop
}
catch (NumberFormatException nfe){
System.err.println("Enter a number less than "+cutOff);
}
}//end while
Could someone explain me some situation (example) when we can use this construction?
try{
//dangerous code here
} finally {
//always called
}
I really understand how it works but newer use in real situation.
Pretty much any time you have something like a Closeable, where you need to explicitly call close() to release the underlying resource, you want to put that call in a finally block, like:
FileReader f = whatever();
try {
// do some stuff with f
return;
}
finally {
f.close();
}
Even if no exception is thrown, and the return inside the try block is run, the resource will still be closed correctly.
try {
isWorking = true
//doStuff that might or might not succeed
} finally {
isWorking = false;
}
another example:
public void actionPressed()
{
if( isLoading )
return;
try {
isLoading= true;
doTheLoad);
} finally {
isLoading = false;
}
}
Some of the common scenarios:
Prevent resource leak:
Close IO streams and DB connections
Message logging
You might use it close database connections or any other resource - a file, hardware port, etc.
try{
// Do something I care about
} finally {
// Make sure we clean up, regardless of success or failure
}
Here's an example:
InputStream in = new FileInputStream(...);
try {
/ * use in here */
} finally {
in.close();
}
Basically, no matter what happens, in will always be closed. Without this, in could stay open until the garbage collector collects it (could be a long time). This is a problem because:
There is a limit on the number of files / network connections you can have open at once
Open network connections will continue to tie up resources on the remote end too (DB connections are a good example)
Closing an input stream also flushes it generally (flushing writes anything in the inputstream's buffer)
For instance when you read a file:
InputStream is = new FileInputStream("...");
try {
// do stuff
}
finally {
is.close();
}
This way your file is always closed, even if there is an exception.
openFile();
try {
int i = Integer.parseInt(someString);
String sub = someString.substring(2);
System.out.println(i+sub);
}
finally {
closeFile();
}
as you can see, there might several Exceptions be thrown during a code passage and you possibly don't want to catch every of them.
also there could an Error be thrown, which you should not catch!
in any way you want to close your file, before the method ends, so you put that in the finally-block
Look at this article, Java Exception Handling - Basics. Here described clearly about exception and where it is used.
This is a very common pattern:
InputStream stream = // acquire stream...
try {
// do stuff with stream that might throw...
}
finally {
IOUtils.closeQuietly(stream);
}
Note, IOUtils is a library from the Apache Commons project. You should always close the stream in a finally. closeQuietly eats any exceptions that might be thrown while trying to close the stream (which is OK because you can't do anything about it).
Especially we can use for data base connection close related code in finally block. if program throws any exception in this case DB connection will release .
This is example in JDBC.same can be applicable in session.close() in Hibernate.
try{
//dangerous code here
} catch(Exception e){
//Do some thing releted to your exception
} finally {
//close DB connection or close your hibernate session.
//always called
}
Well, let's say you open a connection to a database and make some queries. If a SQLException is raised by one of the queries, you're supposed to close the connection before doing something else. If no exception is raised, you're still supposed to close it.
So the try {} catch () {} is there to catch those SQLExceptions and do something about them, while the finally {} is there to close the connection in either case.
This would be a very common scenario, but the same is true with any resource that needs to be freed no matter what happens while using it.
I have a method that periodically (e.g. once in every 10 secs) try to connect to a server and read some data from it. The server might not be available all the time. If the server is not available the method throws an exception.
What would be the best way to implement a wrapper method that doesn't throw an exception except if the server wasn't available for at least one minute?
Keep track of when the last time you successfully reached the server was. If the server throws an exception, catch it and compare to the last time you reached the server. If that time is more than a minute, rethrow the exception.
In pseudocode.
//Create Timer
//Start Timer
bool connected = false;
while (!connected)
try {
//Connect To DB
connected = true;
}
catch (Exception ex) {
if (more than 1 minute has passed)
throw new Exception(ex);
}
}
You will have to record the time that you originally try to connect to the server and then catch the exception. if the time that the exception is caught is more than the original time + 1 minute, rethrow the exception. If not, retry.
Ideally you can put a timeout on the call to the server. Failing that do a thread.sleep(600) in the catch block and try it again and fail if the second one doesn't return.
Remember that exception handling is just a very specialized use of the usual "return" system. (For more technical details, read up on "monads".) If the exceptional situation you want to signal does not fit naturally into Java's exception handling system, it may not be appropriate to use exceptions.
You can keep track of error conditions the usual way: Keep a state variable, update it as needed with success/failure info, and respond appropriately as the state changes.
You could have a retry count, and if the desired count (6 in your case) had been met then throw an exception
int count = 0;
CheckServer(count);
public void CheckServer(count) {
try
{
// connect to server
}
catch(Exception e)
{
if(count < MAX_ATTEMPTS) {
// wait 10 seconds
CheckServer(count++)
}
else {
throw e;
}
}
}
You can set a boolean variable for whether or not the server connection has succeeded, and check it in your exception handler, like so:
class ServerTester : public Object
{
private bool failing;
private ServerConnection serverConnection;
private Time firstFailure;
public ServerTester(): failing(false)
{
}
public void TestServer() throws ServerException
{
try
{
serverConnection.Connect();
failing = false;
}
catch (ServerException e)
{
if (failing)
{
if (Time::GetTime() - firstFailure > 60)
{
failing = false;
throw e;
}
}
else
{
firstFailure = Time::GetTime();
failing = true;
}
}
}
}
I don't know what the actual time APIs are, since it's been a while since I last used Java. This will do what you ask, but something about it doesn't seem right. Polling for exceptions strikes me as a bit backwards, but since you're dealing with a server, I can't think of any other way off the top of my head.