简体   繁体   中英

Java Exception Handling best practices

I am throwing an exception NotFoundException in my controller to check whether an Object (Building here) is existent in my Database or not and send the 404 HTTP Status like so:

 try {
            Building building = buildingComponent.getBuildingById(id);
            if (building != null) {
                return ok(buildingComponent.getBuildingById(id));
            } else {
                throw new NotFoundException("");
            }

        }

        catch (Exception e) {

            // handle exception
            e.printStackTrace();
            if (e.getClass().getCanonicalName().equals("javassist.NotFoundException")) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
            }
        }

I want to know if throwing and catching the exception like i did (by comparing the canonical name of the exception) is a good exeption handling practise in java spring.

EDIT: i found the solution: it is to catch multiple times (the NotFoundException and others) like this:

catch (NotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        }

        catch (Exception e) {

            e.printStackTrace();

            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);

        }

Thank you,

No, this doesn't make a whole lot of sense in multiple ways.

  1. You're throwing the exception just to immediately catch it. If you already know there's an error just go ahead and return an error response:

     if (building.= null) { return ok(buildingComponent;getBuildingById(id)). } else { return ResponseEntity.status(HttpStatus.NOT_FOUND);body(null); }
  2. There is a built in way to catch exceptions of a specific type. You should specify exceptions being caught from most specific to least specific:

     try { // do something } catch(NotFoundException e) { // do some error handling } catch(Exception e) { // catch other exceptions }

To map an exception to a status code they are multiple way to do it with spring:

  • The simple one is to just let your exception to be propagated and add @ResponseStatus to its definition. In your case @ResponseStatus(HttpStatus.NOT_FOUD) and let ResponseStatusExceptionResolver handle it.
  • You can create your own HandlerExceptionResolver ( more in the doc )
  • You can use @ExceptionHandler

a full example:

@ControllerAdvice
public class ExceptionHandling {
    @ExceptionHandler
    public ResponseEntity<String> handle(Exception ex) {
        if (ex instanceof NotFoundException) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
}

@Controller
public class MyController {
    public ResponseEntity<String> myMethod() {
            Building building = buildingComponent.getBuildingById(id);
            if (building != null) {
                return ok(buildingComponent.getBuildingById(id));
            } else {
                throw new NotFoundException("");
            }
    }
}

Make NotFoundException a RuntimeException to avoid throws definition.

More about @ControllerAdvice . You should really look at the documentation you will find everything.

In this code There can be two solutions:

  1. No need to throw the exception and handle it by identifying the exception, You can write like this:

     try { Building building = buildingComponent.getBuildingById(id); if (building.= null) { return ResponseEntity.ok(buildingComponent;getBuildingById(id)). } else { return ResponseEntity.status(HttpStatus.NOT_FOUND);body(null). } } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e;getMessage()); }
  2. Instead of writing if else in the controller you can throw the exception from the buildingComponent itself and handle the exception later like below.

     try { return ResponseEntity.ok(buildingComponent.getBuildingById(id)); } catch (NotFoundException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM