I am building an API service and a lot of the methods have nothing to return but I want to be able to return a status message to the caller to let them know we are done all though all my front end changes to an action are optimistic, sometime we might have to revert based on some CRUD failing. The obvious fix here would be to have a try catch in these methods and send appropriate messages back to the client.
What I was wondering is if there was a way that I could write a generic try/catch block and be able to attach it to all method calls. I used to do this in python using decorators. I don't want to explicitly have the try catch in each method if that makes sense. Is there a way to do this in Java? I am using Spring MVC, so maybe that has some features for this? I wasn't really sure of what to search on google for and wasn't getting any relevant results.
This below thing is generic to Java and not covering Spring.
From all method calls, you can define to say it throws the generic "Exception" as below
public void writeList() throws Exception {
So that in the main function, you can capture using a try block and log it.
Related
For example, if I had the following class that I want to test:
public class SomeClass{
public void someMethod() {
try {
//Some code, where comething could go wrong
} catch (Exception err) {
//Handling it amounts to logging the problem and trying to continue
}
}
}
If I then test this method with JUnit, then if something does go wrong in the try clause and the catch code is run, then the test will pass.
I want to make it so that the test will fail if the catch clause instructions are run.
I did think of a few ways I could try and write tests so that I get an equivalent sort of functionality, but there are reasons for each one that I do not want to approach it that way. It seems like trying to fail the test if any catch clause is reached is the cleanest way to do this, if that is in fact possible
Notes:
I know I could verify certain features of the code and check if they are a certain value/have been run a number of times with Mockito. However I want a solution where if changes were made to the test method that radically altered how it worked (but not what task was essentially being carried out) then I won't have to rewrite the test.
Unfortunately, just to make this proble more difficult, I am unable to make any modifictions to the source code. This position is out of my control so I have to work within these confines.
EDIT:
SomeClass is the class that I wish to test. It is not the actual JUnit test. I have edited my original question to try and clarify this.
I've had to deal with this sort of problem before. I ended up mocking the logging sub-system (not simple but not overly complex) and listened for the 'interesting' logging calls, and then flagging failures when it happened.
Remember that you are testing the behavior of this function. Your test should not care (so not test) that an exception is caught, just that the behavior you want happens.
This means that if you want to test that something is (or isn't) logged. Then you have to verify somethings is logged. In several of my applications I have made a distinction between debug logging and important logmessage. The latter we send through a class (in our case we used the Facade design pattern). that we can mock (and thus test the calls). For most applications, much of the developer logging does not have to be tested, so in those cases you should ignore that.
I don't know of any framework which let you assert exceptions were thown and handled in the method and not propagated. From the problem description I'd see two approaches, both using BDD:
Assert a line of code inside the catch block is not invoked - the logger would be a good option as #Thirler suggests
Assert the Exception constructor is not invoked
Both have problems:
Not very clean as you desire because it is tightly coupled to the actual code being executed.
Any exception handled in the code will trigger a failure.
You could try using aspectj to instrument the code and flag that an exception has been thrown while executing SomeClass.someMethod.
In a general way,
-1- Checking that some function f() throws an exception
try {
f();
// notify test failure here
} catch (...) {
// success
};
-2- Checking that it doesnt
try {
f();
} catch(...) {
// notify test failure here
}
you may consider using assert
what is assert you may ask:
An assertion is a statement in the JavaTM programming language that enables you to test your assumptions about your program. For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light.
I'm not going through the details as I couldn't explain it better than its own documentations.
I wonder if I always have to use try-catch-error blocks that clutter the code a lot, if I want to catch an error.
Or can I somehow define a global error catcher?
Especially regarding Java EE Webapps.
For every unhandled ex I'd like to log to a specific file, and display a general error page to the user.
I thought I might achieve that with aspects. But for aspects to catch on #AfterThrowing, I too have to introduce try-catch blocks. And as there is no central class for the backing-facades, I would have to surround every backing method with trycatches.
Then the aspect would take them, but I need something to catch without explicit throws exceptions.
How could I to that?
You are looking for the declare soft construct. This will wrap the given exception in a SoftException (an AspectJ-specific RuntimeException) so that it does not need to be explicitly handled. Then you can handle all of these exceptions with some AfterThrowing advice.
declare soft only exists in code style AspectJ (ie- there is no annotation for this). So, you will need to compile your code using the AspectJ compiler, but you can still use load-time weaving for this if you like.
See here:
http://www.eclipse.org/aspectj/doc/released/progguide/quick-other.html
And here:
http://www.eclipse.org/aspectj/doc/released/adk15notebook/declare-soft.html
Here's a code snippet that shows how it can be done:
aspect ErrorHandler {
declare soft : Exception : within(*);
after() throwing(Exception e) : handler(e) {
// do something...
}
}
This will route all exceptions in your system through your custom error handler. And you won't need to explicitly catch or throw them.
It's simple and powerful. Perhaps too powerful, though. I'd recommend refining and being more precise about exactly which exceptions should be softened and which ones need to be advised, but this is the basic idea.
You don't have to do this in every method.
You should not catch an exception that you can't "handle". Handling means more than just rethrowing or logging or printing a stack trace. I think handling means implementing a meaningful recovery strategy.
It might mean "the buck stops here": You're Gandalf on the bridge at the edge of a layer boundary, and no exception shall pass. You don't want users to see nasty messages, so you catch and route them to a friend, easy to understand page that tells them what to do next.
Finally isn't always necessary, but it's perfect for cleaning up resources like file handles and database cursors.
If you cannot handle an exception, there's no shame in adding the throws clause to the method signature and letting callers figure out what they want to do.
In the general case, there is no mechanism to do this - Java does not have what you're looking for.
However, depending on your circumstances, it might be possible.
web.xml Exception Handler
The web.xml file allows you to define a URL to be used to handle specified exception type. (See, for example, http://wiki.metawerx.net/wiki/Web.xml.ExceptionType).
Since you're writing a webapp, you may be able to just let the exceptions throw all the way to the top, and then handle them this way.
Custom interceptor
You mention that you have backing-facades. Depending on how they're being constructed, you may be able to put a generic proxy in front of them to catch and handle the exceptions you're interested in. You've tagged your question with spring, to you might want to look at Spring AOP Proxies.
There might be other ways to get what you want, but it will depend on the specifics of your application's architecture.
The finer control you have of the exceptions, the easier it will be to debug/provide a meaningful message.
To which extent? I would link that to the complexity / expected lifetime of your application. The bigger those are, the finer should be your handling.
I see two main approachs:
User approach: You get at least one exception handling for each UI action (so you can say: "Do not push that button AGAIN").
Debugger approach: Every method has its control.
Keep in mind that most handling could be just logging of rethrowing of the exception.
More to the point, most probably, your Java EE framework will have log options in its configuration files (many of them working with java.util.loggin or log4j). You could tweak that; of course, what is send to each log category will depend of the framework implementation (so maybe not all ERROR messages will be Exceptions).
Let's say I have a function that looks like this:
public void saveBooking(/* some inputs */) {
//save into database
}
Before saving into database, I have to do various validations. What I can do in my main program is like this:
//do all the validations and do any necessary handling. Then...
saveBooking(/*inputs*/);
With this, I'm sure that all the data have to pass all the validations required before saving into database. However, this means that the function saveBooking() closely depends on the validation methods. Every time I want to call saveBooking(), I have to make sure that I don't forget to call the validations.
Alternatively, I can put all the validations inside the function itself so that all I should do is to call the method and everything is taken care of. However, in order to handle all the errors independently, I have to do make the function throw exceptions and catch in the main program. It should look something like this:
public void saveBooking(/* some inputs */) /* throws various exceptions */ {
//various validations
//save into database
}
//...and in the main program...
try{
saveBooking(/*inputs*/);
}
catch(MyException1 e1){
//do something
}
catch(MyException2 e2){
//do something
}
This also means I have to create multiple exceptions on my own. The good thing is I don't have to worry what validations I have to put before hand.
With these, I'm not sure which one is the best code design. I personally prefer the first method which is more readable but it depends on each other too much and it's getting worse when I need to use it in many places.
Definitely the first option over the second. I consider the second to be an abuse of exceptions. Exceptions are meant for exceptional circumstances, and failing validation is not "exceptional."
Every time I want to call saveBooking(), I have to make sure that I don't forget to call the validations.
Put the validation logic into a separate method, and have saveBooking() call the validation method before it does anything else.
public List<ValidationError> validateBooking(/* args */)
{
// as #Jared Farrish suggests, return a list of validation errors
}
public boolean saveBooking(/* args */)
{
List<ValidationError> errors = validateBooking(/* args */);
if (errors.size() != 0) return false; // validation failed
// save to the database
return true;
}
The checking should usually be carried out within the function itself so that there is no possibility of trying to save the data without first validating it. Without those checks within the function, you could find a client trying to save without validation and that's rarely a good thing.
But you're not restricted to using exceptions for this, you can simply return an error code of some sort to be checked by the caller. While I usually don't care whether errors are done by exceptions or return codes, there are some that may see this a an abuse of exceptions.
The validation code is probably still left as a separate function since your own code may wish to call it without doing the save as well. Something like (pseudo-code):
def validateStuff():
if stuff is not valid:
return WTF
return OK
def saveBookings():
rc = validateStuff()
if rc != OK:
return rc;
save the information
return OK
You'll still likely have exceptions caught by your call to saveBookings if only to handle I/O errors and the like, but it's not absolutely necessary: you could catch those exception within the function as well and translate them to a return code.
I tend to like one reporting method from each function so I (for example) don't have to try/catch and check return codes.
You are definitely doing the right thing by validating everything before insertion, you should also validate if everything that you are inserting will fit or meets the constraints in your database to avoid an unexpected SQLException, which you won't be expecting and will go all the way to the top.
I would recommend creating a custom exception with some attributes to describe the cause of the error, this way you only have to worry about catching one kind of exception.
Aditionally I would definitly put the validation inside the method, so it is always called.
A 3-tiered approach is fairly common in which you have the following 3 layers:
Client interface. This can include JavaScript validation for a web application or some basic SWT validation on GUI controls.
A Business layer. This layer knows the business rules. This is where you'd, typically, want to put your server-side validation. Anything that should be saved, changed, etc should be done via the business layer (this way you always have your validation and you don't care about your data store).
A Data layer. This layer is typically "dumb". Just save, delete, select, etc; whatever the business layer requests this layer simple does it.
This was very simplified but it gives you a decent way to separate different types of logic for easier maintenance.
It is not a good idea to put lot of code into one place. It is also not good idea to throw checked exceptions.
Assumption that I have method like
void A(long input) {
......
}
Basically, it works well when the input is long or could succeed convert other types to long.
But, when some wrong data inputs, there will throw NumberFormatException. So a robust method should be
void A(long input){
try{
...
}catch(NumberFormatException e){
}
}
However, some developers argue that the project is a BS application. So the input is passed from the web ui. So it could confirm the input is valid. And no needs to handle this exception.
But I think it is a must. What do you think? Thanks.
If the method accepts a long, then there's no conversion within the method itself -- the argument will be converted as it's pushed onto the stack, before the method is called, and you won't be able to catch the conversion error within the method itself.
If you want to pass a String that has the argument, then you'd be doing your own conversion -- and would either need to catch the exception or let it be thrown. Either way can be equally valid, and the choice depends on how you want to handle invalid values. If you're just going to be throwing an exception that says "this isn't really a number" or something, then you may as well just let the exception be thrown.
Whether or not to catch exceptions inside a function is really a choice. The function specification helps.
In your case, however, since the function does not return anything, how is the caller meant to know that something wrong happened? If it does not matter, then catching may be fine. If it does matter, then propagating the exception is a good way of notifying about the error's existence (unless the function signature is changed).
I think it's better to have a try-catch block that is never used than not having one and need it. The fact that the input is passed to the Web-UI means that any validation logic can be modified in the future.
However, what you need to do is to make sure that the user is notified of the error.
Sometimes, we are 99.5% sure that an exceptional condition can't occur in a piece of code. But if the remaining 0.5% can harm the application or database consistency, it might be better to catch an exception and throw a runtime exception before bad things happen:
private void String(String validatedStringWithALongValue) {
try {
long l = Long.parseLong(validatedStringWithALongValue);
// ... do what has to be done
} catch (NumberFormatException oops) {
Exception e = new RuntimeException(oops);
log.error("Bad news - validation failed or has been bypassed", e);
throw e;
}
}
The answer to this question depends on your system design.
If it is the responsibility of the Web UI to perform data type validation, then it is reasonable for the next level to assume that validation has been done, and allow the NumberFormatException to propagate. However, at some point though, the server side code should catch the (unexpected) exception, log it, and produce an appropriate HTTP response code.
If it is not the responsibility of the Web UI to perform data type validation, then the next level needs to generate a suitable (user friendly) error message, and make it easy for the user to correct it. (For instance, a web UI implemented in HTML only won't be able to validate data to any degree.)
If your system design does not clearly specify where responsibility for the various kinds of validation belongs, then the design is flawed.
You should also consider whether it is a good idea to pass numbers as strings after they have been validated. This may be necessary; e.g. if the layers are in separate webapp containers. But if the validation and business logic are in the same servlet, then the former should be passing an int or long and not a String representation of a number to the latter.
Finally, if any of the notionally internal web apis are in fact exposed, you should at least do enough validation to protect them against hacking. For instance, if the user-facing Web UI is HTML + Javascript, then there must also be an exposed HTTP-based API that it communicates with. It is a simple matter for a hacker to circumvent your GUI and talk directory to the HTTP API. So the HTTP API should validate requests at least to the extent necessary to foil attempted exploits.
I know we can declare the exception for our method if we want it to be handled by the calling method. This will even allow us to do stuff like write to the OutputStream without wrapping the code in try/catch block if the enclosing method throws IOException.
My question is: Can anyone provide an instance where this is usually done where you'd like the calling method to handle the exception instead of the current method?
Edit: I meant calling method instead of super class in the last line.
In general, I would say design your exception flow so that the exception is caught by the code that can actually take appropriate action.
This usually means that in a "library" method (or, some kind of general utility method in a large project), you will be throwing exceptions not catching them.
On the other hand, if you have a situation where you find yourself declaring your method to throw an exception that you believe in practice will hardly ever occur (e.g. serialisation generally involves all sorts of spurious checked exceptions which in practice won't occur, e.g. if you're deserialising an Integer, it's really unlikely that the Integer class is not present, but you still have to catch the appropriate exception), then you have a third option of re-casting to a RuntimeException.
I guess by "super class" you mean the code that called your method.
If you expect the caller to know more about the problem compared to your method, than you can pass this responsibility up the calling stack.
In general, if you do not know how to handle the problem, don't. Ether pass it or wrap it in another exception.
If you can't handle the error at the point in a sensible way (e.g. displaying error message, taking an alternative path, etcetera), then just let it bubble up.
If you want the error to be handled at a different level of the application.
Here's a semi-concrete example. Let's say I've got a web application which is implemented as a series of states and actions. Suppose that, while a state is being processed, a database access causes an SQLException to be thrown. This would not happen during the normal operation of my application; it would only happen if there were something wrong with the database.
The method that access the database doesn't need to know what my procedure for handling semi-fatal errors like this is. That logic implemented at a higher level — in the method that processes the state — and it's essentially the same for any runtime error, whether it's literally a RuntimeException or not: spit out a nice-looking error message to the user telling them to contact tech support.
Imagine if I had to add a try/catch block performing this logic to every method that accessed the database and could possibly throw an SQLException. That's what's called a nightmare.
I have used expections to as part of transferring information between architectural layers of application.
For Example:
if the DAO (Database Access Layer) gets a SQLException it throws a customized DAOLayerException which is caught by the businesslayer which in turn throws an exception which is caught by the presentation layer.
This was for unchecked exceptions.
I usually follow the practice of throwing checked unchecked exceptions (not handling them) if the function is to be used by numerous caller or are unknown at the time of development of the function.
In web frameworks (like spring) you often let errors propagate and container will deal with them (by showing error page or message to the user, rolling back transaction, etc).
Also, there are lots of java errors you never catch, like OutOfMemoryError. You can catch them, but you can't deal with them properly.
You asked for an example, and here is a common one.
If you are writing code to read a particular file format, these normally declare IOException. The reason for this is that it might be used by a desktop app (which wants to put up a dialog box) or a text utility (which wants to write an error message) or a web app (which wants to return an error code). Exception handling allows you to do that.
Yes, I would declare it so it propagates up until a parent calling method which would actually handle it (display on UI, break there, ..)
For Instance, I may have some helper methods in a sendEmail method. If a helper method say checkEmailAddress() produced an exception, I would want sendEmail to know about it, which can further propagate it up or do an alert on UI "email is wrong"