I am using a third party api to get user authentication in spring.
I need to catch the exceptions that occur when trying to connect to that api, like connection time out and page not found (if their server is down).
Right now I am trying to do this with below code. Is this sufficient to catch these exceptions?
public boolean userAuthentication(String userName) {
try {
if(hasAccess(userName)) {
return true;
} else {
return false;
}
} catch (IOException e) {
logger.info("exception occured "+ e);
return false;
}
}
Here hasAccess is the third party api, I cannot change that method. Whereas I need to catch these exception and give appropriate response to the user.
does hasAccess(String) define any throws statement?
Does it define that it throws IOException?
Do you have the access to the source code of this method? If you do then you can go and and check if they are handling any exceptions thrown or they are re-throwing any runtime exceptions.
To be on safer side, you should catch runtime exceptions, as the error is unpredictable for you, so you can gracefully handle errors.
It is impossible to tell whether this is sufficient without looking at the implementation of hasAccess(), since that is the function that will throw the error.
However, if you really need to catch this exception, you can always use
try {
if (hasAccess(userName)){}
} catch (Exception e) {
//caught
}
This isn't always good practice, since Exception will catch every exception, but it is a solution if you're looking for one.
Related
I have two ids (id1, id2) and I want to fetch data from server if first fails.
try
{
loadData1(id1);
}
catch(Exception e)
{
loadData2(id2);
}
Is this a good practice or is there any alternative for this?
This is not a good practice. Try to use the catch block for handling the error/exception and logging the error information. You can have a condition check to see if the loadData1(id1); operation is a success so that in the next try-catch block you can add the logic loadData2(id2);
boolean loadSuccess=false;
try
{
loadSuccess=loadData1(id1);
}
catch(Exception e)
{
//error handling or logging code goes here
}
if(!loadSuccess)
{
try
{
loadData2(id2);
}
catch(Exception e)
{
//error handling or logging code goes here
}
}
loadData1 fails when it throws an exception. But loadData2 is there to handle it as long as -
loadData2 function call in catch is again wrapped in an effective try-catch.
loadData2 is function that already has exception handling implemented.
The rest of the code should continue execution if one of the conditions is met.
I have a question about Java method introspection, specifically concerning exceptions. Say I have the following code:
private String getCustomReportResponse(HttpsURLConnection customReportConnection) {
int responseCode = 0;
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
}
}
Let's say both statements in the try block are capable of throwing an IOException - in which case, the translateIntoRelevantException method is invoked, which looks like this:
private void translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
throw new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
throw new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
So, whatever happens, either a String is returned, or an exception is thrown. Except the getCustomReportResponse method does not compile without adding a return statement after the catch block, which is absolutely unreachable. In fact, if I put the contents of translateIntoRelevantException inside the catch block, it compiles, which seems daft to me.
I should add, the exceptions being thrown are runtime exceptions, but I've also tried making them checked exceptions, but the problem persisted.
Could someone please explain why?
This is a common problem that "rethrow" helper methods face.
The compiler does not know (and there is no way to indicate) that the method translateIntoRelevantException will never return.
As such, it thinks that there is a code-path that continues after try block. So you have to put in a "dead-code" return null (or throw new RuntimeException("should never come here").
You don't have to put it after the try block, you can put it inside the catch.
try {
responseCode = customReportConnection.getResponseCode();
return httpResponseBodyExtractor.extractResponseBodyFrom(customReportConnection);
} catch (IOException e) {
translateIntoRelevantException(responseCode, e);
throw new RuntimeException("should never come here");
}
It's probably prettier to have the helper just return the exception instead of throwing it. Then you can do
throw translateIntoRelevantException(responseCode, e);
Compilation of getCustomReportResponse should not rely on the implementation of translateIntoRelevantException for multiple reasons:
implementation of translateIntoRelevantException might not be available (it could be in a separate class, in a separate library);
otherwise any change in translateIntoRelevantException could break all of the calling methods.
As an alternative you can return an exception and then throw it in a client code:
private IOException translateIntoRelevantException(int responseCode, IOException e) {
if(is5xxResponseCode(responseCode)) {
return new ServerResponseException("Could not generate report - returned response code " + responseCode, e);
}
return new ReportException("GeminiReportException: Unable to parse response from HTTP body when requesting custom Gemini report.", e);
}
then call it like this:
throw translateIntoRelevantException(responseCode, e);
I did extensive research on exceptions, but I'm still lost.
I'd like to know what is good to do or not.
And I'd also like you to give me your expert opinion on the following example :
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
} catch (IOException e) {
log.error("step1", e);
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Is it ok to throw a personnal exception (MyProcessException) in each step in order to manage a global try...catch...finally ?
Is it ok to manage each known exception for each step ?
Thank you for your help.
EDIT 1 :
Is it a good practice like this ? log directly in global catch by getting message, and try...catch(Exception) in upper level....
The purpose is to stop if a step fail, and to finalize the process (error or not).
In Controller
public void callProcess() {
try {
myprocess(...);
} catch (Exception e) {
log.error("Unknown error", e);
}
}
In Service
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
log.info("ok");
} catch (IOException e) {
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
log.error(mpe.getMessage(), mpe);
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Thank you.
Edit 2 :
Is it a real bad practice to catch (Exception e) in lower level and to throws a personnal exception ?
Doesn't exist a generic rule,it depends on your needs.
You can throw a personal exception, and you can manage each known exception.
But pay attention, it is important what you want.
try{
exec1();
exec2(); // if exec1 fails, it is not executed
}catch(){}
try{
exec1();
}catch(){}
try{
exec2(); // if exec1 fails, it is executed
}catch(){}
In your example above it may well be acceptable to throw your own custom exception.
Imagine I have some data access objects (DAO) which come in different flavours (SQL, reading/writing to files etc.). I don't want each DAO to throw exceptions specific to their storage mechansim (SQL-related exceptions etc.). I want them to throw a CouldNotStoreException since that's the level of abstraction that the client is working at. Throwing a SQL-related or a File-related exception would expose the internal workings, and the client isn't particular interested in that. They just want to know if the read/write operation worked.
You can create your custom exception using the originating exception as a cause. That way you don't lose the original info surrounding your problem.
In the above I probably wouldn't handle each exception in each step as you've done. If processing can't continue after an exception I would simply wrap the whole code block in an exception handling block. It improves readability and you don't have to catch an exception and then (later on) check the processing status to see if you can carry on as normal (if you don't do this you're going to generate many exceptions for one original issue and that's not helpful).
I would consider whether multiple catch {} blocks per exception add anything (are you doing something different for each one?). Note that Java 7 allows you to handle multiple exception classes in one catch{} (I realise you're on Java 6 but I note this for completeness).
Finally perhaps you want to think about checked vs unchecked exceptions.
The main point of the exception mechanism is to reduce and group together handling code. You are handling them in the style typical for a language without excptions, like C: every occurrence has a separate handling block.
In most cases the best option is to surround the entire method code with a catch-all:
try {
.... method code ...
}
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
The only times where this is not appropriate is where you want to insert specific handling code, or wrap in a custom exception that will be specifically handled later.
Most exceptions, especially IOExcption in your case, represent nothing else but failure and there will be no handling beyond logging it and returning the application to a safe point, where it can process further requests. If you find yourself repeating the same handling code over and over, it's a signal that you are doing it wrong.
One very important rule: either handle or rethrow; never do both. That is what you are doing in your example: both logging and rethrowing. Most likely the rethrown exception will be caught further up in the call stack and logged again. Reading through the resulting log files is a nightmare, but unfortunately quite a familiar one.
int step = 0;
try
{
step = 1;
...
step = 2;
...
step = 3;
...
}
catch (Exception1 e)
{
log ("Exception1 at step " + step);
throw new MyException1 ("Step: " + step, e);
}
catch (Exception2 e)
{
log ("Exception2 at step " + step);
throw new MyException2 ("Step: " + step, e);
}
...
I'd say it depends on your needs...
If step2 can execute correctly even if step1 failed, you can try/catch step1 separately.
Otherwise, I would group all steps in one try/catch block and made sure that the individual steps produce a log message when they fail.
That way you don't litter your code and still know what went wrong
It's ok to catch each known exception, so you can log what exception occure, and why it did.
Here some links to exception handling patterns/anti-patterns:
Do:
http://www.javaworld.com/jw-07-1998/jw-07-techniques.html
Don't:
http://today.java.net/article/2006/04/04/exception-handling-antipatterns
http://nekulturniy.com/Writings/RebelWithoutAClause/Rebel_without_a_clause.html
About creating your own exceptions, it's certainly useful if you're creating an API, a framework or another piece of reusable code, but in a regular application, it's more debatable and I personally would suggest to stick to existing exceptions.
Does it make sense to throw exception from catch block just to log the message so that we are sure that what is causing the exception?
Code
public void saveLogs(Logs logs) throws RemoteException
{
try
{
LogsOps.saveLogs(logs);
}
catch (RemoteException e)
{
log.info("RemoteException is thrown while trying to save logs ", e);
throw new RemoteException("RemoteException caused while trying to save", e);
}
}
In response to one of the comments below that this method would throw StackOverFlow Exception, here the actual implementation of log.info which just displays those errors.
/** Log the message and the exception with a level of INFO.
* #param message - The message text.
* #param t - An exception to display.
*/
public void info(Object message, Throwable t)
{
String nullSafeMessage = (message != null) ? message.toString() : t.getClass().getSimpleName();
log.info(nullSafeMessage, t);
}
So there never would be Stackoverflow exception thrown.
It depends on what's going to catch the exception higher up. If nothing else is going to log the message, then sure, it makes sense - although I'd probably rethrow the original exception instead of creating a new one:
catch (RemoteException e)
{
log.info("RemoteException is thrown while trying to save logs ", e);
throw e;
}
Ideally, though, you'd have a single catch block higher up the stack, which would log appropriately - if you're just logging the exception, that can get all the information anyway.
It may make sense to catch/log/rethrow when you want to log information which isn't present in the exception, such as parameter values.
Presuming that you will eventually handle the propagated exception, this tactic of catch-log-rethrow just clutters up the log file. Imagine that this is done the entire way up the stacktrace - you end up with reams of redundant error information that serves no useful purpose.
If you are not handling the exception you shouldn't log it either.
Besides for logging, this approach may also be used to perform necessary cleanup in case of a failure before returning control to a caller further up the stack.
For example
InputStream is = new InputStream( ... )
try {
is.read(...);
return is;
} catch ( IOException ioe ) {
is.close();
throw ioe;
}
This is, of course, a somewhat special use which can be avoided elegantly most of the time by using a finally clause - but not always, as the case above demonstrates.
I have something similar to this.
void func() {
try {
//socket disconnects in middle of ..parsing packet..
} catch(Exception ex) {
if(!ex.getMessage().toString().equals("timeout") || !ex.getMessage().toString().equals("Connection reset")) {
debug("Exception (run): " + ex.getMessage());
ex.printStackTrace();
}
}
Why is it that when I get a connection reset exception or a timeout exception, it still goes inside the condition. I tried without toString and with no luck.
You shouldn't catch all exceptions and then test the error message of the exception. Instead only catch those exceptions that you intend to handle - for example SocketTimeoutException.
catch (SocketTimeoutException ex)
{
// Do something...
}
With your current code you may be catching some other type of exception that you weren't expecting. Currently you will just ignore this exception, not even logging it. This can make it very difficult to debug what is going on. If you have an exception that you can't handle you should either rethrow it or log it.
I want to catch all exceptions
If you really want to do that then you can write your code as follows:
catch (SocketTimeoutException ex)
{
// Do something specific for SocketTimeoutException.
}
catch (Exception ex)
{
// Do something for all other types of exception.
}
Regarding your specific error, you have written:
!a.equals(b) || !a.equals(c)
This expression always evaluates to true. What you meant was:
!a.equals(b) && !a.equals(c)
Or equivalently:
!(a.equals(b) || a.equals(c))
Note that by rewriting your code as I suggested above you completely avoid having to write this complicated boolean expression.
It's really not safe to rely on exceptions messages to know what is the cause of your exception.
In your case you can try to catch more specific exceptions, such as SocketTimeoutException and the classic IOException :
void func() {
try {
//socket disconnects in middle of ..parsing packet..
} catch(SocketTimeoutException ex) {
//In case of Time out
} catch(IOException ex){
//For other IOExceptions
}
}
Sources :
[Socket.connect()][3]
Even if you prefer to seek informations in exceptions messages, you shouldn't check if the message simply is equal to "timeout" but if the message contains "timeout"
[3]: http://download-llnw.oracle.com/javase/6/docs/api/java/net/Socket.html#connect(java.net.SocketAddress, int)