0

In my service layer I have a method to login a user into the system. This method receives 3 arguments: String username, String password, int roleId.

I need to perform couples of check in my service layer:

  • A User exist in the system with the username parameter.
  • The Password of the User matches with the password parameter.
  • A Role exist in the system with the roleId parameter.
  • The User has access to the Role with the roleId parameter.
  • The User is not locked. ...

If any of these checks fail then the service layer should tell the controller that the login has failed and why it has failed.
If all of these checks pass then the service layer should tell the controller that the login has passed.

My concern is in case of a check fail, how can I communicate it from the service layer to the controller. Should I throw an exception? Or should I send an error code?

I think I have these options:

OPTION 1:

Throw an exception whenever a check fail. So my service method could be:

public void login(String username, String password, int roleId) throws UserServiceException;

And this could be the logic:

boolean check1Flag = isUserExist(username);
if (!check1Flag) {
   throw new UserServiceException("No user exist with username '" + username + "'");
}
...

OPTION 2:

Send an error code whenever a check fail. If all of these checks pass then send 0 as code. So my service method could be:

public int login(String username, String password, int roleId) throws UserServiceException;

And this could be the logic:

boolean check1Flag = isUserExist(username);
if (!check1Flag) {
   return -1; // -1 means No user exist with username paramter
}
...

OPTION 3:

Send false whenever a check fail. If all of these checks pass then send true. So my service method could be:

public boolean login(String username, String password, int roleId) throws UserServiceException;

And this could be the logic:

boolean check1Flag = isUserExist(username);
if (!check1Flag) {
   return false; 
}
...

Option 3 looks clean but I dont know how to inform controller which error occurred in this case.

Are there any other options? Are there any generally accepted design guidelines for this scenario?

Thanks

srh
  • 1,661
  • 4
  • 30
  • 57

2 Answers2

1

I think it depends on whether you need the information in the controller or not.

If for example it is some kind of web site and the login controller will just show the user "Login failed" screen then I would go for Option 3 . And if you want you can also log the error in the service layer.

If you need the login controller to act different for different errors. For example to say "You don't have the role" or "Your account is locked", then I would go for Option 2. Maybe you can make a responses enum or something like that instead of integers to make code clear.

I wouldn't choose option 1 because I prefer not to use exceptions for common scenarios handling. Also since you want to know what happened in the controller you will need to add some integer or enum code in the exception anyway or to parse the exception message.

Veselin Davidov
  • 7,031
  • 1
  • 15
  • 23
0

This is an opinion-based question, but you can borrow a leaf from the servlet specification, where the HttpServletRequest#login method throws a ServletException in the event of a failure. The reasons are obvious:

  1. An error-handling paradigm that fits into the general exception handling mechanism of JavaEE in general. You can handle your exceptions using stock JavaEE constructs like <error-page> and global execption handling mechanisms you'll find in things like CDI and JSF

  2. A compact communication package. Your exception can unequivocally communicate that

    • That the request failed (#3)
    • An exception message, that may be more user-friendly
    • A context-specific exception-class name
kolossus
  • 20,559
  • 3
  • 52
  • 104