I am experimenting with Clean Architecture in my project and want to implement simple REST communication logic. I've started with simple "user login" use case. I am curious if my understanding of boundaries crossing is correct.
The main goal is to implement communication between network and business(use case) layers.
So here is the structure I plan to have:
LoginInteractor - business layer
LoginProcessor - interface from Network layer
NetworkLoginProcessor - implementation of LoginProcessor
LoginInteractor will hold the reference to LoginProcessor(interface). LoginProcessor will have one method login(name, password) which returns UserEntity or throws an exception.
I am not sure how to deal with the exceptions since they may occur due to different reasons. I am thinking of introducing UserLoginError and have specific error as the cause. For example:
public class UserLoginError extends RuntimeException{
...
}
public class BadCredentials extends RuntimeException{
...
}
public class NetworkError extends RuntimeException{
}
public class UserBlockedError extends RuntimeException{
...
}
public class UserAccountNotActivatedError extends RuntimeException{
...
}
So LoginInteractor may look like this:
public class LoginInteractor {
private final LoginProcessor loginProcessor;
@Inject
public LoginInteractor(LoginProcessor processor){
this.loginProcessor = processor;
}
/**
* Performs login and returns user data.
*
* @throws UserLoginError
* //TODO list all possible causes
*/
public User loginUser(String userName, String password){
return processor.login(userName, password);
}
}
I feel that passing UserEntity and the exceptions from the networking layer(LoginProcessor) first to business layer and then directly to UI layer is not correct.
Does it mean that I need to create a separate User object returned in LoginInteractor#loginUser() method?
What about the exceptions?
What have I misunderstood?
Looking forward to your suggestions.