1

I am developing a web application using Java and Spring Boot. Specifically, I am reviewing some code written by other developers. I use Postman to make HTTP calls to my application. There are cases where my application needs to inform the caller of certain situations. In this example, the developer of the application threw a JwtTokenException to the caller in case of IOException.

try {
    myToken = methodThatObtainsAToken(tokenInput);
}catch(IOException ex) {
    throw new JwtTokenException("Error 401", JwtStatusResponse.JWT_NOT_VALID); // TODO: cambiare
}

When something goes wrong here is what happens on POSTMAN: enter image description here

I have so many other very similar situations in this code and I have to do the following thing: I have to replace the code throw new JwtTokenException so that it throws exceptions that make the caller understand (so I can see them with Postman) that an HTTP error has occurred (with some code). In the example I wrote I wrote "Error 401" only as a string. There are other places in the code where I use "Error 500", "Error 302" and so on.. But these are just information strings, and do not correspond to the real error thrown to the client. How do I throw correct exceptions that raise "HTTP errors"?

wishyouwerehere
  • 163
  • 1
  • 3
  • 8
  • this will probably solve your problem: https://stackoverflow.com/questions/51465987/spring-boot-http-status-without-throwing-exceptions?rq=1 – Ali Tahir Mar 10 '21 at 09:02

3 Answers3

1

If most of the exceptions are handled like in code you have posted and you don't want to change return types of methods, just replace them with

catch(Exception e){   
    throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}

which will give the following output

{
    "timestamp": "2021-03-10T09:25:04.823+0000",
    "status": 404,
    "error": "Not Found",
    "message": "Not Found",
    "path": "/account"
}

if you'd like to get exception info just add

catch(Exception e){   
    throw new ResponseStatusException(HttpStatus.NOT_FOUND,null, e);
}

response:

{
    ...
    "message": "404 NOT_FOUND; nested exception is java.lang.ArithmeticException",
    ...
}

note that it will be logged if you didn't declare your own exception resolver

 2021-03-10 15:28:20.043  WARN 11392 --- [nio-8090-exec-2] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "Not Found"; nested exception is java.lang.ArithmeticException]

Instead of null you could pass a string describing exception, which will replace "message" in json response.

Aidos Rustem
  • 145
  • 8
0

One usually returns response entity with body object and status set to provide interesting information:

        return ResponseEntity.ok()
        .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, trackDTO.getId().toString()))
        .body(result);

Response Entity is org.springframework.http.ResponseEntotuy which provides a lot of convenience methods to setup all the headers and whatever is necessary.

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
0

From your attached screenshot. Your application returned 401 Unauthorized. I think you no longer need to pass the error code since you get it from the response itself. Exceptions do not return Http Status Code and you as a developer is responsible to telling your app which error code to return. For example in your RestController

@GetMapping(path = "{id}")
public ResponseEntity<ResponseModel> getEmployee(@PathVariable("id") String id) {
    ResponseModel result = employeeService.findById(id);
    return new ResponseEntity<>(result, HttpStatus.OK); // <--- THIS
}

And in your custom exception handler, you can do it like this.

NOTE: This triggers when you call from your Jwt Verifier Filter

@ExceptionHandler(value = ExpiredJwtException.class)
public ResponseEntity<Object> handleExpiredJwt(ExpiredJwtException e) {
    ApiException apiException = new ApiException(e.getLocalizedMessage(), HttpStatus.UNAUTHORIZED);
    return new ResponseEntity<>(apiException, UNAUTHORIZED);
}
Rye
  • 445
  • 4
  • 15