Java Exception handling within "events" - java

I would like to get a second opinion on how to handle Exceptions within "events" (key input, screen update etc). In this case I have control over the event-sender.
So a module is set to handle an event (it implements a listener interface, and is registered against an event sender):
public void DefaultSet ( CardData oldDefault, CardData newDefault )
{
}
The event sender is simply:
for ( Enumeration e = listeners.elements(); e.hasMoreElements(); )
{
RetrieverListener thisListener = (RetrieverListener) e.nextElement();
thisListener.DefaultSet( oldDefault, newDefault );
}
So if/when something goes wrong in the receiver:
Should I try to cope with the exception there, and never throw anything back to the sender? Sometimes the listeners don't have the "context" to handle an error correctly, is that right?
Is it frowned on to throw an exception back to an event-sending module, to be handled in a documented way? e.g. "Throwing an IOException will result in a reset.. ". This seems non-standard from the javadocs I have read.
Should I just log and ignore the exception when something goes wrong & nothing can be done about it?

The Java convention is that listener methods do not throw exceptions. Obviously, programming errors might make a listener throw a RuntimeException, but there's no way the event source can recover from that because it will have left the program's objects in some unknown, maybe inconsistent state.
It is therefore up to the listener to catch checked exceptions and either recover from them (roll back a transaction, for example) or report them to some other object. I often use an ErrorHandler interface that looks something like:
public interface ErrorHandler {
public void errorOccurred(String whatIWasTryingToDo, Exception failure);
}
An event listener tells its ErrorHandler about errors that have occurred.
public class SomeClass implements SomeKindOfListener
private final ErrorHandler errorHandler;
... other fields ...
public SomeClass(ErrorHandler errorHandler, ... other parameters ... ) {
this.errorHandler = errorHandler;
...
}
public void listenerCallback(SomeEvent e) {
try {
... do something that might fail ...
}
catch (SomeKindOfException e) {
errorHandler.errorOccurred("trying to wiggle the widget", e);
}
}
}
I initialise event listeners with an implementation of this that handles the failure in whatever way makes sense at that point in the application. It might pop up a dialog, show a flashing error icon in the status bar, log an audit message, or abort the process, for example.

When nothing can be done about you should log and send a message to the user. If something goes wrong that may damage data or give wrong results if you can't recover you should close the application.

The usual approach is to ignore the issue. Listeners should not throw unchecked exceptions.
A better approach would be to catch and log RuntimeExceptions. These generally indicate a programming error. If a widget on the screen throw an NPE, then there is no reason why the rest of the window should not finish painting. The user can then save their data and restart or otherwise work around the issue. In the case of Errors it generally means that there is a serious situation, such as OutOfMemeory and catching will just result in thrashing. Nobody bothers doing this.

Related

How can I override Dropwizard's default resource exception handling?

Suppose I've got an endpoint in Dropwizard, say
#GET
public Response foo() { throw new NullPointerException(); }
When I hit this endpoint it logs the exception and everything, which is great! I love it. What I love less is that it returns a big status object to the user with status: ERROR (which is fine) as well as a gigantic stack trace, which I'm less excited about.
Obviously it's best to catch and deal with exceptions on my own, but from time to time they're going to slip through. Writing a try catch block around the entire resource every time is fine, but (a) it's cumbersome, and (b) I always prefer automated solutions to "you have to remember" solutions.
So what I would like is something that does the following:
Logs the stack trace (I use slf4j but I assume it would work for whatever)
Returns a general purpose error response, which does not expose potentially privileged information about my server!
I feel like there must be a built-in way to do this -- it already handles exceptions in a relatively nice way -- but searching the docs hasn't turned up anything. Is there a good solution for this?
As alluded to by reek in the comments, the answer is an ExceptionMapper. You'll need a class like this:
#Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
#Override
public Response toResponse(RuntimeException runtime) {
// ...
}
}
You can do whatever logging or etc. you like in the toResponse method, and the return value is what is actually sent up to the requester. This way you have complete control, and should set up sane defaults -- remember this is for errors that slip through, not for errors you actually expect to see! This is also a good time to set up different behaviors depending on what kind of exceptions you're getting.
To actually make this do anything, simply insert the following line (or similar) in the run method of your main dropwizard application:
environment.jersey().register(new RuntimeExceptionMapper());
where environment is the Environment parameter to the Application's run method. Now when you have an uncaught RuntimeException somewhere, this will trigger, rather than whatever dropwizard was doing before.
NB: this is still not an excuse not to catch and deal with your exceptions carefully!
Add the following to your yaml file. Note that it will remove all the default exception mappers that dropwizard adds.
server:
registerDefaultExceptionMappers: false
Write a custom exception mapper as below:
public class CustomExceptionMapper implements ExceptionMapper<RuntimeException> {
#Override
public Response toResponse(RuntimeException runtime) {
// ...
}
}
Then register the exception mapper in jersey:
environment.jersey().register(new CustomExceptionMapper());
Already mentioned this under the comments, but then thought I would give it a try with a use case.
Would suggest you to start differentiating the Exception that you would be throwing. Use custom exception for the failures you know and throw those with pretty logging. At the same RuntimeException should actually be fixed. Anyhow if you don't want to display stack trace to the end user you can probably catch a generic exception, log the details and customize the Response and entity accordingly.
You can define a
public class ErrorResponse {
private int code;
private String message;
public ErrorResponse() {
}
public ErrorResponse(int code, String message) {
this.code = code;
this.message = message;
}
... setters and getters
}
and then within you resource code you can modify the method as -
#GET
public Response foo() {
try {
...
return Response.status(HttpStatus.SC_OK).entity(response).build();
} catch (CustomBadRequestException ce) {
log.error(ce.printStackTrace());
return Response.status(HttpStatus.SC_BAD_REQUEST).entity(new ErrorResponse(HttpStatus.SC_BAD_REQUEST, ce.getMessage())).build();
} catch (Exception e) {
log.error(e.printStackTrace(e));
return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(new ErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage())).build();
}
}
This article details Checked and Unchecked Exceptions implementation for Jersey with customized ExceptionMapper:
https://www.codepedia.org/ama/error-handling-in-rest-api-with-jersey/
Official Dropwizard documentation also covers a simpler approach, just catching using WebApplicationException:
#GET
#Path("/{collection}")
public Saying reduceCols(#PathParam("collection") String collection) {
if (!collectionMap.containsKey(collection)) {
final String msg = String.format("Collection %s does not exist", collection);
throw new WebApplicationException(msg, Status.NOT_FOUND)
}
// ...
}
https://www.dropwizard.io/en/stable/manual/core.html#responses
It worked for me by simply registering the custom exception mapper created in the run method of the main class.
environment.jersey().register(new CustomExceptionMapper());
where CustomExceptionMapper can implement ExceptionMapper class like this
public class CustomExceptionMapperimplements ExceptionMapper<Exception>

Is handling all possible (unchecked) Exceptions good practice?

Currently my signup looks like this:
public void signup(User newUser) throws Exception {
log.info("Sign up: " + newUser.getEmail());
if (restService.emailAlreadyExists(newUser.getEmail())) {
throw new Exception("Email already in use.");
}
List<Role> roles = new ArrayList<Role>();
roles = roleRepository.findAllOrderedByName();
roles.add(roleRepository.findByName("user"));
newUser.setRoles(roles);
newUser.setPassword(restService.getHashedValue(newUser.getPassword()));
try {
em.persist(newUser);
} catch (Exception e) {
throw new Exception("Just noobs use apps with less bugs. Try again. Now!");
}
log.info(newUser.toString());
userEvent.fire(newUser);
}
In first order I'm just interested in two messages (will become FacesMessage) for the user. To prevent other cryptic messages for the user, I even would need to extend the try-block up to roles.
Well, that would be bad practice, I guess. Also using a generic Exception smells, they say. But: I detect following documented Exceptions in this small piece of code:
IllegalStateException
IllegalArgumentException
EntityExistsException
TransactionRequiredException
ObserverException
Even not speaking about the eight(!) Exceptions of the method getSingleResult() of javax.persistence.TypedQuery.
Should I really handle all Exceptions in this example, or is it ok to skip a few (and/or maybe even use a generic Exception like above).
Best practice is: catch all exceptions separately and make as more custom log messages as possible. It's easier to understand faulty situations and to act accordingly.
Reality in a typical business application is: try to group your exceptions (ex. group all possible exceptions caused by your method input, all the ones throwed by the db etc. etc.) and learn that sometimes you will put the infamous catch (Exception e) or rethrow a generic exception with a generic message... or people will start calling you about logs growing like elephants.

How To Throw customized Block Exception in Java

I would like to know that how can i trow customized block exception in java.i will explain it on following example.
#login
//Below code snippet do log in functionality.
mycode goes here
String name="abc";
if name.equals("ABC")
{
enter to system ...
}
Console Out Put
You have error on log in
#register
//Below code snippet do register functionality.
mycode goes here
let say in #login annotation there is a error from my code.java should throw it like a good readable way.The exception should be like regular exception and where it generate.i mean code block in this case it is log in.If register it should say u have an error in register code block.
Also i don't declare annotation on top of method.In my case there is no such a method and everything handle the annotations.
as a example
Student Class
class student{
#login
login related codes goes here
#View Result
view result related codes goes here
#logout
logout code goes here
}
As a example you can consider above class as a selenium script.in scripts we don't use any methods.i want to implement back end class(annotations) that gives and meaningful errors on happens in the related code block.(log in,view result,...)
when ever user write a new script he can reuse my annotation.
Actually this is a idea that i wanna implement.Because if i do like that it will be easy for my app users.so I would like to know that can it possible to do and if so how can i do it.If you know another way Please let me know your ideas.Thanks.
I'm not convinced I fully understand the question but if you're looking for creating a custom exception, you can do the following:
if name.equals("ABC") {
// do something
} else {
throw new CustomException("Name did not equal 'ABC'");
}
where the custom exception is defined as:
public class CustomException extends Exception {
public CustomException(String msg) {
super(msg);
}
}
And then wherever you need to handle the exception, it would look like:
try {
// do something that might throw a CustomException
} catch (CustomException ce) {
ce.printStackTrace();
// or do something more useful to handle the exception
}
And if you go this route, I would call it something other than CustomException, call it something that is relevant to the problem the exception pertains to, for example NameNotEqualException.

Is return boolean for operation success / fail a good practice in Java?

I have some function works with database.
I have set a try/catch for error handling here, and display a message, It works fine.
Now the class calling this delete function need to know if there is a error or not. In my case : refresh the GUI if success, nothing to do if fail (as there already show up a message message dialog).
I come up a idea to return boolean in this function.
public static Boolean delete(int id){
String id2 = Integer.toString(id);
try {
String sql =
"DELETE FROM toDoItem " +
"WHERE id = ?;";
String[] values = {id2};
SQLiteConnection.start();
SQLiteConnection.updateWithPara(sql, values);
} catch (SQLException e) {
Main.getGui().alert("Fail when doing delete in DataBase.");
System.out.println("Exception : "+ e.getMessage());
return false;
}
return true;
}
Don't know if this is good or bad, please tell.
EDIT :
Here is more detail for How do I use :
Let's say the code above is inside Class A,
in Class B :
public boolean deleteItem(int id){
int i = index.get(id);
if(theList[i].delete()){ //<---- here is the function from Class A
theList[i] = null;
index.remove(id);
retutn true;
}
retutn false;
}
I need to pass the boolean in more than one class, I don't know if that can better through...
in Class C :
public void toDoList_deleteItem(){
MyButton btn = (MyButton)source;
int id = btn.getRefId();
List toDoList = Main.getToDoList();
if(toDoList.deleteItem(id)){ //<-------function in Class B
Main.getGui().refresh();
}
}
Edit 2 :
I have notice the question is somehow more likely asking "What should I handle a Exception at database Layer that affect to GUI Layer ?"... Something like that. Please correct me if the question title should be edit.
It looks like you are returning a boolean status to indicate that an exceptional condition had occurred. Generally, this is not a good practice, for two reasons:
It encourages an error-prone way of handling exceptions - it is very easy to miss a status check, leading to ignored errors
It limits your API's ability to report errors - a single pass/fail bit is not always sufficient, it may be desirable to pass more information about the error.
A better approach would be to define an application-specific exception, and use it in your API. This forces the users of your API to pay attention to exceptional situations that may happen, while letting you pass as much (or as little) additional information as you find necessary. At the same time, your code does not get polluted with if (!delete(id)) { /* handle error */ } code on each API call, shrinking your code base, and improving its readability.
Can you tell me more about "define an application-specific exception", or show some code example please?
Here is how I would do it:
public class DataAccessException extends Exception {
... // Define getters/setters for passing more info about the problem
}
...
public static void delete(int id) throws DataAccessException {
try {
... // Do something that may lead to SQLException
} catch (SQLException se) {
// Do additional logging etc., then
throw new DataAccessException("Error deleting "+id, se);
}
}
Note: It is common to give custom exceptions four constructors mirroring the constructors of the Exception class to allow exception chaining. The constructors are described here.
As long as you do not want the caller to know what happens, just that it fails (and that failing is part of its intended behavior) you should be fine.
That being said, I am noticing this: Main.getGui().alert("Fail when doing delete in DataBase.");.
It would seem that you are accessing the GUI layer from some other place. This might cause issues should you decide to multi-thread your application. Also, it is usually considered good practice to have your layers not intersect.
Don't return a Boolean, return a boolean. Since this is not an exception / error condition, it is fine.
Exceptions should be used when you don't expect a failure.
In your case, if it's fine for you that a SQLException is thrown and does not affect your program, it's ok to return a boolean.
If the SQLExcetion causing the delete to fail can cause problems in another part of your application it's better to throw an exception.
Edit:
Based on your edits, it seems that you are doing some maintenance and cleaning when an error happens. In such a case I would recommend to use Exceptions better than using booleans to control the execution.
This question is primarly opinion based. Personally I would prefer not to catch the exception at that point.
Depending on what the caller of delete() should do, you might need other resulutions. So you should better add a throw statement and let the calling method decide if the error is critical - or if it can proceed.
Just true and false is not necessary enough to let the caller decide correctly. He won't know if deletion fails due to database errors, due to foreignkey constraints, or something else.
letting the exception bubble up the call stack will provide the caller with the exact error going on, increasing the chance to handle the error in a proper way, or just displaying a custom error message helping the user to take proper actions.

Should I throw IllegalArgmentException when 'user of given id not exist'?

Say we have a method changeUserName(Long id,String newName) which invokes the repository's findUser(Long id) to find the right user entity and then change its name. Is it appropriate to thow an IllegalArgmentException when findUser returns null ? Or should I instead throw a custom UserNotExistException (extends AppException extends RuntimeException) ?
UPDATE:
RuntimeException:
#nachokk #JunedAhsan Actually I deliberately make all the exceptions unchecked , because I think this way makes client code clean , easy for debuging and more safe. As to those "unhandled" ones, I'll catch them all on the top of layers thus avoiding showing them on the UI.
This is due to the fact that many clients catch checked exceptions and then just ignore it, and in some cases they don't know how to handle it. This is a hidden trouble.
Clarification:
Sorry for my bad English. What I meant is if the changeUserName should throw an IllegalArgumentException, not the findUser method. And another question: how to differentiate illegal argument from business rule violation?
You should use UserNotExistException. The name is very declarative of what is happening. In my opinion you should to avoid returning null but if you do you have to document it.
UPDATE
I was thinking and as #JunedAhsan suggest, UserNotExistException could be better a CheckedException (extends from Exception and not RuntimeException).
From this link: Unchecked Exceptions : Controversy
If a client can reasonably be expected to recover from an exception,
make it a checked exception. If a client cannot do anything to recover
from the exception, make it an unchecked exception.
/**
* #return User found or throw UserNotExistException if is not found
*/
public User findUser(Long id) throws UserNotExistException{
//some code
User user = giveMeUserForSomePlace();
if(user == null){
throw new UserNotExistException();
}
return user;
}
It depends on how you handle exceptions.
IllegalArgumentException is ok if you only display error report by using e.getMessage() and you don't care repetitive string appending code.
Here is some advantage I find by using custom exceptions:
1. Reduce reptetive code:
Let's say changeUserName is surely not the only case you'll load User, so this code snippet below will happen everytime you invoke repository.findUser(Long id)
if (user == null) {
throw new IllegalArgumentException("No such user found with given id["+ userId +"]");
}
On the other hand, an ad-hoc exception is much more handy:
if (user == null) {
throw new UserNotExistException(userId);
}
public class UserNotExistException extends RuntimeException {
public UserNotExistException(Long id) {
super("No such user found with given id["+ id +"]");
}
}
2. You need more support from your exceptions:
Maybe you need to return status code or something like that. An custom exception hierachy may do some help:
see this answer for detail.
I would too suggest to use UserNotExistException but with a difference that instead of it being unchecked exception (by virtue of extending RuntimeException), make it checked exception (extending Exception if AppException is not doing this already).
This will make sure that caller of changeUserName handles UserNotExistException exception and make the code a bit robust.

Categories