Reputation: 57
I am implementing a REST api webservice which is fetching data from a MySql database. It is written here that we dont need to handle database exception explicitly. I have catch blocks in the Service layer. I have the following questions.
1- How do i send the appropriate error message to the respective model view from the catch block?
2- Is Service the right layer to catch the exception?
I have the following code
Controller
@RequestMapping(value = "/saveUser", method = RequestMethod.POST)
public ModelAndView saveUser(@ModelAttribute User user, BindingResult result)
{
ModelAndView mv = new ModelAndView();
validator.validate(user, result);
if(result.hasErrors()) {
mv.setViewName("addUser");
}
else {
service.saveUser(user);
mv.setViewName("redirect:/users/listAllUsers");
}
return mv;
}
Service
public void saveUser(User user) {
try {
userDao.saveUser(user);
} catch(DuplicateKeyException e) {
//Here i want to send "User already exist"
} catch(DataAccessException e) {
//Here i want to send "Databae unreachable"
}
}
UserDAO
public void saveUser(User user) {
String sql = "INSERT INTO User (fname, lname, address, phone)"
+ " VALUES (?, ?, ?, ?)";
jdbcTemplate.update(sql, user.getFname(), user.getLname(),
user.getAddress(), user.getPhone());
}
}
Upvotes: 0
Views: 5279
Reputation: 44
@dbreaux 's answer is correct.You should customize an exception.
public class UserException extends RuntimeException {
// You can add some custom variables
// such as error codes, error types, etc.
}
Then,you should define a ControllerAdvice to handle this Exception:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class UserControllerAdvice{
@ExceptionHandler(value = UserException.class)
public ModelAndView handleUserException(UserException ex){
// Generate corresponding results(ModelAndView) based on exception.
// example: Put the error message to model.
return new ModelAndView("prompt_page",ex.getMessage());
}
}
Last,you can throws UserException
in your Service.
public void saveUser(User user) {
try {
userDao.saveUser(user);
} catch(DuplicateKeyException e) {
throw new UserException("User already exist");
} catch(DataAccessException e) {
throw new UserException("Databae unreachable");
}
}
Upvotes: 3
Reputation: 5115
You want to isolate the web-specific behaviors from the service layer, and from the data layer, and I think the best way to do that is to throw a new, checked, domain-specific Exception
that matches the meaning of each case you want to handle differently in the Controller.
For example, DuplicateUserException
, SystemUnavailableException
. Then the Controller catches those and adds the correct case to the Model.
Upvotes: 1