Search code examples
javaexceptionhttp-status-code-404http-status-codes

HTTP Status in case of EntityNotFoundException


I'm working on the exception handling in my application. In my service I have this method:

public Optional<Entity> getEntityById(Long id) {
    return Optional.of(EntityMapper.fromEntityToDto(repository
            .findById(id)
            .orElseThrow(() -> new EntityNotFoundException("No entry was found for" + " id: " + id))));
}

In my exception handler I have the following

@ControllerAdvice
public class ControllerAdvisor extends ResponseEntityExceptionHandler {

    @ExceptionHandler(EntityNotFoundException.class)
    public ResponseEntity<Object> handleEntityNotFoundException(EntityNotFoundException ex, WebRequest request) {

        ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND, "Entity not found", ex.getMessage());
        return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
    }
}

I have seen examples where they do this here and here but it seems to me like an abuse of the HttpStatus. The resource is the API endpoint (which is fine) and not the entity that was not found. What would be the best way to handle this use case?


Based on IQbrod's answer I created an exception:

@ResponseStatus(value = HttpStatus.NO_CONTENT)
public class MyEntityNotFoundException extends RuntimeException {

    public MyEntityNotFoundException(String message) {
        super(message);
    }
}

which I now throw instead of the EntityNotFoundException


Solution

  • The eternal debate between 404 and 204.
    Let's try to have an example here. Your entity is now a box filled with magical objects.
    Box1 : It's a box with a beautiful pony inside.
    Box2 : It's an empty box.

    Let's ask for the first box content :

    GET https://{URL}/v1/boxes/1/content
    
    • 200 (Pony)

    Now let's ask for the content of the second box :

    GET https://{URL}/v1/boxes/2/content
    
    • 204 NO CONTENT

    Let's ask for the box n°3 (the box itself, not the content):

    GET https://{URL}/v1/boxes/3
    
    • 204 NO CONTENT, In your storage you couldn't find any box with number 3

    Let's now ask what's inside box n°3:

    GET https://{URL}/v1/boxes/3/content
    
    • 404 the box doesn't exists.
      Here 404 does mean that the resource couldn't be found, user didn't check if the box exists and his request is nonsensed (which is basically 4xx).

    PS: You might have a different opinion on the subject, this is only my interpretation.