Pass an exception up to the method - java

I've got a method which throws an exception itself and calls a method which catches another exception:
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authenticated()) {
return new UsernamePasswordAuthenticationToken(
name, password, new ArrayList<>());
} else {
return null;
}
}
private boolean authenticated(){
try {
thirdPartyClass.login();
return true;
} catch (ThirdPartyException e) {
return false;
}
}
thirdPartyClass.login() is from an api I don't own and it is a void method so all unsuccessful authentications must be catched.
ThirdPartyException exception gives a good explanation of what went wrong so I'd like to have it as my error message instead of:
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
which comes from AuthenticationException
How can this be achieved?

What about something along these lines:
public Authentication authenticate(Authentication authentication)
throws AuthenticationException
{
try {
thirdPartyClass.login();
return new UsernamePasswordAuthenticationToken(
name, password, new ArrayList<>());
} catch (ThirdPartyException tpe) {
throw new AuthenticationException(tpe.getMessage(), tpe);
}
}

Do you want to get message from ThirdPartyException? If so, then you can do something like:
private boolean authenticated() throws ThirdPartyException {
thirdPartyClass.login();
return true;
}
if not, then kindly explain it
Updated
public Authentication authenticate(Authentication authentication)
throws AuthenticationException
{
try {
authenticated();
return new UsernamePasswordAuthenticationToken(
name, password, new ArrayList<>());
} catch (ThirdPartyException ex) {
throw new AuthenticationException(ex.getMessage(), ex);//or any other child exception of AuthenticationException
}
}

Just replace the function with this code:
private boolean authenticated(){
try {
thirdPartyClass.login();
return true;
} catch (ThirdPartyException e) {
return false;
} catch (Exception ex) {
return false;
}
}
If the thirdPartyClass.login(); is handling the exception and printing error on console then you can only ignore the message, and consider that thirdParty function is telling you that username and password tokens are not valid ones.

Related

Prettifying exception handling in function

Can this func. not be prettified?
Can the the catch clause be left empty, I have heard it's frowned up on.
apiClient.accountList() is where the exception can occur.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
try {
for (Account account : apiClient.accountList()) {
if (account.getUuid().equals(accountUuid)) {
return Optional.of(account);
}
}
} catch (ApiException e) {
return Optional.empty();
}
return Optional.empty();
}
If you're very motivated to avoid the duplicate return statement, a simple tweak to the control-flow should do it. As mentioned in the comments, logging exceptions is often a good idea.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
Optional<Account> result = Optional.empty();
try {
for (Account account : apiClient.accountList()) {
if (account.getUuid().equals(accountUuid)) {
result = Optional.of(account);
break;
}
}
}
catch (ApiException e) { /* Log exception */ }
return result;
}
You can use Stream, assuming getUuid does not throw an ApiException.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
try {
return apiClient.accountList().stream()
.filter(account -> account.getUuid().equals(accountUuid))
.findAny();
} catch (ApiException e) {
/* Log exception */
return Optional.empty();
}
}
Actually instead of collection returning methods like accountList() it more and more makes sense to use Streams, accountStream().

Java HTTPException Return status code

please advise on the below scenario
How can I handle Http Status code
try {
validateUser(a,b);
} catch(HttpException he){
response = new ResponseEntity<>(status code);
}
....
validateUser(String a, String b) throws HttpException {
if(some condition) {
throw new HttpException(); // I want throw set status code to 401 so that I can catch it up there in catch block
}
}
import java.xml.ws.http.HTTPException;
try {
validateUser(a,b);
} catch(HTTPException he){
response = new ResponseEntity<>(HttpStatus.valueOf(he.getStatusCode()));
}
private void validateUser(String a, String b) throws HTTPException {
if(some condition) {
throw new HTTPException(HttpStatus.UNAUTHORIZED.value());
}
}

How to catch already caught exception?

I have the follow the following filter:
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
try {
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
} catch (XssAttackException e) {
request.getRequestDispatcher("/XssAttack").forward(request, response);
}
}
and the class XssAttackException is:
public class XssAttackException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
after debugging the code, I realized that somewhere in the spring framework all the exceptions are being caught. Now I need a way that my catch bock also run.
UPDATE
inside XSSRequestWrapper we have:
#Override
public String getHeader(String name) {
String value = super.getHeader(name);
return stripXSS(value);
}
And
private String stripXSS(String value) {
if (value != null) {
value = persianUtf8(value);
if (!value.equals(Jsoup.parse(value).text())) {
throw new XssAttackException();
}
value = Jsoup.parse(value).text();
for (Pattern scriptPattern : patterns) {
if (scriptPattern.matcher(value).matches()) {
throw new XssAttackException();
}
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
Please don't assume this is answer for your question.Assumed too long comment.
I created my CustomException class.
public class CustomException extends RuntimeException {
}
and created custom Servlet class as your XSSRequestWrapper and throw my custom exception in constructor.
public class MyServlet implements ServletRequest {
public MyServlet() {
throw new CustomException();
}
// other override methods go here
}
and in my filter class
try {
chain.doFilter(new MyServlet(), response);
} catch (CustomException e) {
System.out.println("xxxxxxxxxxxxxxx I got it xxxxxxxxxxxxxxxxxxx");
}
This code work fine. At your program , I think there has some exception has occured and you did not catch on them. So , this exception object has miss from your try block of your filter class and handled by Spring container.

How check if throwed exception

if i have something like this:
public User findUserByEmail(String email) throws CustomerNotFoundException{
List<User> users = new ArrayList<User>();
users = sessionFactory.getCurrentSession().createQuery("from User where email = ?").setParameter(0,email).list();
if (users.size() > 0) {
return users.get(0);
} else {
throw new CustomerNotFoundException();
}
}
And in this moment i want to check the returned findUserByEmail(String email) method whether it return the User object or CustomerNotFoundException in the end.
I tried in this way
private boolean searchCustomer(String email) throws CustomerNotFoundException{
if (hibernateDao.findUserByEmail(email).getClass() == User.class) {
....
} else { .... }
}
Is it a good way or are there betters?
No. Nonononono.
Use the catch keyword to catch the Exception.
try {
User thingie = hibernateDao.findUserByEmail(email);
}
catch (CustomerNotFoundException cnfe) {
// TODO some logic on failure
}
Also remove the throws statement from your searchCustomer method's signature if you're using a try / catch mechanism and not rethrowing the Exception.

Catching and rethrowing an exception from a boolean method does return false whereas not doing anything causes the method not to return

I have a general query regarding the java programming language and how it deals with exceptions and methods returning boolean.
Please not that although the example below deals with Spring/Ldap/ActiveDirectory, my question is only about java and exceptions.
public boolean doAuthenticate(String userAndDomain, String password) {
UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(replaceBackSlashWithAtSign(userAndDomain), password);
try {
Authentication authentication = adAuthenticationProvider.authenticate(userToken);
return authentication.isAuthenticated();
} catch (BadCredentialsException e) {
log.error("Authentication failed - wrong username\\password", e);
throw new BadCredentialsException("Authentication failed - wrong username\\password", e);
} catch (AuthenticationException e) {
log.error("Authentication failed - AuthenticationException", e);
throw new AuthenticationException("Authentication failed - AuthenticationException", e) { };
}
}
If any of BadCredentialsException or AuthenticationException is rethrown by the authenticate method, then the doAuthenticate method returns false.
However if for some reason another runtime exception is thrown by adAuthenticationProvider.authenticate(), then the method does not return false and does not return at all...
I am just curious to know why that is...
edit:
LdapAuthentifier authentifier = new LdapAuthentifierImpl();
boolean didAuthenticate = authentifier.doAuthenticate(VALID_USER, INVALID_PASSWORD);
A System.out.println of didAuthenticate does show false if one of the two specified exceptions are thrown whereas another exception halts execution of the program and the System.out.println is never reached...
edit 2:
public static void main(String[] args) {
LdapAuthentifier authentifier = new LdapAuthentifierImpl();
boolean didAuthenticate = authentifier.doAuthenticate(VALID_USER, INVALID_PASSWORD);
}
I understand what happened. Here is the explanation.
The exception I actually saw in the logs was BadCredentialsException but this exception is never thrown by adAuthenticationProvider.authenticate and therefore never rethrown by the below method.
What actually happened was that the authentication.isAuthenticated() was just returning false and I was passing this boolean value to the client code.
I am including the method again for clarity's sake:
#Override
public boolean doAuthenticate(String userAndDomain, String password) {
UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(replaceBackSlashWithAtSign(userAndDomain), password);
try {
Authentication authentication = adAuthenticationProvider.authenticate(userToken);
return authentication.isAuthenticated();
} catch (BadCredentialsException e) {
log.error("Authentication failed - wrong username\\password", e);
throw new BadCredentialsException("Authentication failed - wrong username\\password", e);
} catch (AuthenticationException e) {
log.error("Authentication failed - AuthenticationException", e);
throw new AuthenticationException("Authentication failed - AuthenticationException", e) { };
}
}

Categories