Is there a better way for catching specific Exception with a message then doing this:
try{
methodThatWillProbablyThrowASocketException();
} catch(SocketException e){
if(e.getMessage().contains("reset")){
// the connection was reset
// will ignore
} else{
throw e;
}
}
For example the HttpStatusException gives me the Method getStatusCode() where i can easily compare if the error status was 404 or 502 and the can decide what to do:
try{
methodThatWillProbablyThrowAHTTPException();
} catch(HttpStatusException e){
if(e.getStatusCode() == 404){
// not found, will not continue
}
if else(e.getStatusCode() == 502){
// server errror, try again
} else{
throw e;
}
}
Most other Exceptions dont give me prober Methods, just the Message.
So my question is, is it the right way to do it? With String compares? Or is there a better way?
Just do one thing .
Collect all types of exception that are likely to be occur for your project.
Make a separate class by extending Exception.
Override the getCause() method.
http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getCause%28%29
public Throwable getCause()
Define codes you want for different exceptions Like null-pointer 101 ,, so on......
The use that class every where . So you have to write exception only once and you can use with as many projects.
After building the class it will be reusable for all your needs
If you getting new conditions, update this class only and all the things will be done
This is a better solution according to me...
This way you can get functionality for which you are looking. you have to make it by yourself.
Relying on code or status code is fine but relying on message could be problematic as the message can change.
You should look to refactor and define multiple exceptions or define codes for different scenarios.
Related
when a function or method encouter error/invalid data, do return false or throw an exception?
Consider a class Loginer has such method :
public boolean login(String username){
//retrieve data...
if(username.equals(record.username)){
return true;
}
return false;
}
then at the main or some other class
String username = "ggwp";
if(Loginer.login(username)){
//successful login, show homepage...
new User(username);
} else {
//invalid username
}
won't it be inefficient as it has been checked two time with if-else statement, one in Loginer, and another one check for true again at main.
won't try catch will do the same? having the Loginer to throw an Exception:
public User login(String username){
//retrieve record data...
if(username.equals(record.username)){
return new User(username);
}
/* Exception if no record found for such username */
throw new MyException("invalid username");
}
then on the main:
String username = "ggwp2";
User theUser;
try{
//sucessful login
theUser = Loginer.login(username);
}catch(MyException e){
//invalid username
}
the try-catch need no check second time for true or false. (this example i use return User object, it could be void and return nothing but the point is, why use boolean which will eventual being check twice?)
some website sources say not to use try-catch for 'code jumping' but in this case it just do the same. (try-catch is just too similar to if-else statement)
So which is correct and why? please guide and sorry if this question is incorrect, im newbie to OO.
Short answer:
You should NEVER use try/catch for "control logic".
As Andy Turner said, "Use exceptions to handle exceptional conditions only."
This is equally true of all languages that support exceptions - not just Java. Useful article:
Best practices for exceptions
PS: try/catch is NOT "just similar" to "if/else". It has a different implementation, a different intent ... and it's FAR more expensive.
ADDITIONAL NOTE:
Exceptions: Why throw early? Why catch late?
https://softwareengineering.stackexchange.com/questions/231057/exceptions-why-throw-early-why-catch-late
In my experience, its best to throw exceptions at the point where the
errors occur. You do this because it's the point where you know the
most about why the exception was triggered.
As the exception unwinds back up the layers, catching and rethrowing
is a good way to add additional context to the exception. This can
mean throwing a different type of exception, but include the original
exception when you do this.
Eventually the exception will reach a layer where you are able to make
decisions on code flow (e.g a prompt the user for action). This is the
point where you should finally handle the exception and continue
normal execution.
With practice and experience with your code base it becomes quite easy
to judge when to add additional context to errors, and where it's most
sensible to actually, finally handle the errors.
Catch → Rethrow
Do this where you can usefully add more information that would save
a developer having to work through all the layers to understand the
problem.
Catch → Handle
Do this where you can make final decisions on what is an
appropriate, but different execution flow through the software.
Catch → Error Return
Whilst there are situations where this is appropriate, catching
exceptions and returning an error value to the caller should be
considered for refactoring into a Catch → Rethrow implementation.
I'd like to know what is the best way or best-practice to handle this kind of situation. Guess a straightforward function like this:
public Object f1() {
Object result = null;
try {
String payload = methodThrowsAnException();
result = payload;
} catch (IOException e) {
throw new IllegalStateException(e); <<<<<<<<<<<<<<<
}
return result;
}
I'd like to know if it's a good practice:
to re-throw the exception or
return a null when something has been wrong inside.
I don't know if I've explained so well.
Re-throwing caught exception is a bad idea. most often, the stacktrace will contain more or less detailed information about your architecture. This would be to useful for an attacker.
I wouldn't allow my app to get into illegal state because of the user's action. In your case, I would say:
try {
String payload = methodThrowsAnException();
result = payload;
} catch (IOException e) {
throw new IllegalArgumentException(<user's input which caused the exception>); <<<<<<<<<<<<<<<
}
There is nothing wrong with returning a null from your method if there is a particular scenario where you expect that exception.
Alternatively you can just allow the Exception to bubble up, and be handled by the caller.
When would I catch and re-throw an exception? When I can convey better meaning by throwing a new exception.
Would I include the original exception when I throw a new one? I would do it if it is a unknown/unexpected scenario which requires further debugging.
Let me share some examples:
Something unrecoverable like Out of DB Connection. I would just let the exception bubble up. It should get handled just before it reaches the user, and probably end up in a generic error message like 'Service not available. Please try again later'.
Something application related... such as backup file not found. In that case I will swallow up the FileNotFoundException and instead I will throw a BackupFileMissingException which is specific to my application. Here I don't need to include the FileNotFoundException because it is an expected scenario and there is nothing further to investigate.
I call some other API and they throw an exception, which is not documented. In this case, I will translate it into my application exception such as InterfaceApiException and include the original exception, so that it can be logged at the REST/Action layer along with the root cause.
At the moment I am developing a website while using the Playframework2. I am just a beginner in programming. I read some books about exceptions but now in the real world , exception handling is really strange.
To be honest I don't really care what exceptions are thrown I handle all exceptions the same way.
return badrequest(); . I only use exceptions for logging.
try{
...
}
catch(Exeption e){
//log
return badrequest();
}
But this is so much boilerplate and it's really annoying to write, because every method throws the same exceptions.
Any tips , hints or resources that you could give me?
edit:
An example would be my "global" config file. Because I need to connect to the db every time I thought i could write a singleton for this problem.
private Datastore connect() throws UnknownHostException, MongoException,
DbAuthException {
Mongo m = new Mongo(dbUrl, dbPort);
Datastore ds = new Morphia().createDatastore(m, dbName);
boolean con = ds.getDB().authenticate(username, password.toCharArray());
if (!con)
throw new DbAuthException();
return ds;
}
This also results in a try and catch every time I want to connect to the db. My problem is I don't think I can handle them diffidently.
A code example :
public static Result addComment(String title) {
try {
Datastore ds = DatabaseConnect.getInstance().getDatastore();
Form<Comment> filledForm = commentForm.bindFromRequest();
Comment userComment = filledForm.get();
userComment.setUsername(Util.getUsernameFromSession(ctx()));
User.increasePointsBy(ctx(), 1);
UserGuides.addComment(title, userComment);
} catch (Exception e) {
return badRequest();
}
return redirect(routes.Guides.blank());
}
In this case I was to lazy to write the same try and catch over and over again, and this is duplicated code.
Maybe there is a book that explains how to design a big application with exception handling?
When you invoke a method, you do not necessarily have to catch the exceptions right there. You can let your callers handle them (declaring a throws clause if it is a checked exception). In fact, the ability to pass them on to the callers without any additional work is the distinguishing feature of exceptions.
My team has adopted the following coding standard: We throw checked exceptions for those rare cases when we want to recover from a failure, and unchecked exceptions for anything else. There is only a single catch block for the unchecked exceptions in a method so high in the call stack that all requests pass through it (for instance in a ServletFilter). This catch block logs the exception, and forwards the user to the "Sorry, this shouldn't have happened" page.
Have you looked at your code to examine why you're throwing all these exceptions? Exceptions are there for a reason- to tell you that something went wrong. If you're writing too much "boilerplate" try-catch code and you're not in a thousand line application, you have to refactor.
try-catch can be irritating when you have a complex block and can become very monotonous and boilerplate (Marc Gravell even said he usually uses try-finally) but as a new programmer, it would be helpful for you to examine the code that you write and figure out how to either handle or avoid those exceptions.
As akf mentions, ignoring exceptions can also be hazardous to debugging. It will be harder to track down where something catastrophic went wrong if you're missing exceptions leading up to it.
Sometimes, I'll end up having to catch an exception that I know can never happen, such as here
URLDecoder.decode("some string", "UTF-8"); //No unknown encoding possible
or here:
public void methodWithURL(URL url){
URI uri = new URI(url); //No invalud URI syntax possible
}
How do you handle this? I generally log a funny error regarding how the laws of the universe have changed, and then throw a RuntimeException. Is there a better way?
I catch the Exception and wrap it in an Error. from the doc of Error :
An Error is a subclass of Throwable that indicates serious problems
that a reasonable application should not try to catch.
I would skip the funny message.
BTW: I had a case where a piece of code (in a small library) just assumed that an encoding would be available. Only it got deployed on a limited device and exploded at runtime.
Checked exceptions serve to show places in our code where we should pause for a second and consider the paths less traveled (as in "what my app does when network dies" and other corner cases). Wrapping them in IllegalStateException and rethrowing is a sort of a signed contract, where the programmer says: "yes, all risks considered I take full responsibility for the spot right here". If it wasn't for checked exceptions, we would hava no way of knowing a consious decision from a plain lack of thought.
Well, IMHO there is a better way than "log[ging] a funny error regarding how the laws of the universe have changed" because in doing so you are "being cute," which among friends is fine but is not universally (no pun intended) accepted. Your code may be read by others and if your humor falls flat (on them) you haven't really made any friends.
Many style guides make suggestions for impossible exceptions. You can use an empty catch block with the exception parameter being named willNeverHappen; you can place a comment in the empty block; you can throw a runtime exception (probably the best, since you MIGHT misspell UTF-8!)
If you want to be super ambitious, you can write an annotation, like SneakyThrows in Lombok. Whether you would consider this "better" is simply a matter of taste. :)
Note that this question was discussed on https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-cannot-ever-be-thrown.
Here's my solution -- developed for Android but can be easily adapted for "regular" Java:
public class ImpossibleException extends RuntimeException {
public ImpossibleException(#NonNull String whyNotPossible) {
this(whyNotPossible, null);
}
public ImpossibleException(#NonNull String whyNotPossible, Throwable throwable) {
super("Impossible exception: " + whyNotPossible, throwable);
Log.e("Impossible", whyNotPossible, throwable);
}
}
Usage:
try {
byte[] data = "Hello".getBytes("utf-8");
Log.i("Test", "data.length=" + data.length);
} catch (UnsupportedEncodingException e) {
throw new ImpossibleException("Android always supports utf-8", e);
}
The whyNotPossible constructor means there's no need to log the error where it happens, and there's also no need for a comment.
I guess it's a matter of taste if this should be an ImpossibleException extends RuntimeException or an ImpossibleError extends Error.
If you use Lombok in your project, you can annotate the surrounding method with #SneakyThrows which kind of hides checked exceptions in RuntimeException (thus no need to surround by try-catch nor declare it in throws clause).
For instance:
#SneakyThrows(URISyntaxException.class)
public void methodWithURL(URL url){ // No throws here
URI uri = new URI(url); // Assume no invalud URI syntax possible
}
So we are a few guys developing this product that is communicating with a really unstable server. It often returns very strange and corrupt data. During testing we want the resulting crashes to be loud, so we discover them. But every other day we need to demonstrate our product for a potential customer. To the customer the errors will go undiscovered if we just swallow them. I am thinking about implementing something like this around all server communication to quickly switch between swallowing exceptions and crashing:
try {
apiCall();
} catch (Exception e) {
if(!SWALLOW_EXCEPTION) {
throw e;
}
}
Is this an awesome idea, or can it be done in a better way?
I would recommend using a Logger like SLF4J, java.util.logging or Log4j. Any log messages that are 'debugging' but you still want tracked you can put to the DEBUG, INFO or WARN levels based on their severities. Real errors you can save for the 'Error' level.
When you do demos to customers, set your log level to Error so they don't see everything. When you are running normally though, set it to a level to capture the logging level you need.
Swallowing exceptions is never a good practice. By using a logger, you can hide them if it is giving you too much detail. You can always get access to them if you need without recompiling.
This is not pretty. How about implementing a top level (whatever that means in your context) error handler[s] that does that?
Did you intend your code to do this?
try {
apiCall();
} catch (Exception e) {
if(!SWALLOW_EXCEPTION) {
throw e;
} else {
e.printStackTrace();
}
}
If so, if this is the only place that this API is called, it seems ok to me, as long as you realize you will need to recompile for the change to take effect. You could abuse a logging framework to get that done without a recompile like this:
if (logger.isInfoEnabled()) {
throw e;
} else {
logger.error(e.getMessage(), e);
}
But I think most people looking at such a piece of code would be very taken aback. If you want to avoid the recompile, just use a System property:
if (Boolean.getBoolean("development")) {
throw e;
} else {
e.printStackTrace();//you should really use a logging framework anyway and not this.
}
You could use an 'uncaught exception handler' instead. Check out the code at http://stuffthathappens.com/blog/2007/10/07/programmers-notebook-uncaught-exception-handlers/ and http://www.javapractices.com/topic/TopicAction.do?Id=229. You can also write your handler to put the exceptions into a logger.