2017-08-02 55 views
1

我在春天Webstart的应用处理工作...Java的异常重复在一个单独的方法

我有2个(可能更多)的方法是处理多层次的免责条款,如:

... 
    try { 
     employeeService.updateEmployeePartner(employeeId, partner); 
     LOG.info("partner details updated for partner id {}", employeeId); 
     result = new ResponseEntity<>(partner.getId(), HttpStatus.OK); 
    } catch (EmployeePartnerNotFoundException ex) { 
     LOG.error(ex.getMessage() + " employee id: ", employeeId); 
     errorResponse = new ErrorResponse("500", ex.getMessage()); 
    } catch (ReadOperationDeniedException ex) { 
     LOG.error("User doesn't have permissions to update employee's {} details: {}", employeeId, ex.getMessage()); 
     errorResponse = new ErrorResponse("403", "User doesn't have permissions to update employee's details"); 
    } catch (Exception ex) { 
     LOG.error("something went wrong while updating employee's {} partner details: {}", employeeId, ex.getMessage()); 
     errorResponse = new ErrorResponse("500", "unspecified server error"); 
    } finally { 
     result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR 
    } 
... 

另一种方法几乎相同,除了这种变化: employeeService.updateEmployeePartner(employeeId, partner); => employeeService.createEmployeePartner(employeeId, partner); 并在该块中捕获EmployeePartnerAlreadyExistsException

现在,为了减少代码重复,我希望将所有的错误在一个地方(方法)处理代码,所以我取代了上面的代码与下面的

... 
     try { 
      employeeService.updateEmployeePartner(employeeId, partner); 
      LOG.info("partner details updated for partner id {}", employeeId); 
      result = new ResponseEntity<>(partner.getId(), HttpStatus.OK); 
     } catch (Exception ex) { 
      errorResponse = processException(ex, employeeId, "update"); 
     } finally { 
      result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR 
     } 
... 
    private ErrorResponse processException(Exception ex, Long employeeId, String operation) { 
     ErrorResponse errorResponse; 
     if (ex.getClass().equals(EmployeePartnerNotFoundException.class) || 
       ex.getClass().equals(EmployeePartnerExistsException.class)) { 
      LOG.error(ex.getMessage() + " employee id: ", employeeId); 
      errorResponse = new ErrorResponse("500", ex.getMessage()); 
     } else if (ex.getClass().isInstance(ReadOperationDeniedException.class)) { 
      LOG.error("User doesn't have permissions to " + operation + " employee's {} details: {}", employeeId, ex.getMessage()); 
      errorResponse = new ErrorResponse("403", "User doesn't have permissions to " + operation + " employee's details"); 
     } else { // Exception 
      LOG.error("something went wrong while trying to " + operation + " employee's {} partner details: {}", employeeId, ex.getMessage()); 
      errorResponse = new ErrorResponse("500", "unspecified server error"); 
     } 
     return errorResponse; 
    } 

那是一个足够好的方法或者是通过将处理外包给一个单独的方法/类,有没有在上述场景中处理异常的模式?

因为它是一个Spring应用,我也考虑使用Spring的异常处理程序,如:

@ExceptionHandler(Exception.class) 

,但将只包括我的要求的一部分。

回答

1

将@ControllerAdvice与您自定义的ErrorResponse和每个Handler分开使用异常。请参阅Custom error response Spring

示例代码:

0

这就是我最后到底在做什么,与上岩回复沿:

个别异常处理程序相当奏效;请注意,没有必要将这些放在单独的课程中。

但我仍然怀疑是否有一个类似的模式,其中应用程序不是Spring MVC?

public ResponseEntity<?> updatePartnerDetails(@PathVariable("employeeId") Long employeeId, 
                @RequestBody PersonDetails partnerDto) { 
     LOG.info("Updating partner details for employee {}, partner details {}", employeeId, partnerDto); 
     validateRequestValues(partnerDto); 
     // Try-catches were around this call 
     Person partner = PersonMapper.fromPersonDetails(partnerDto); 
     employeeService.updateEmployeePartner(employeeId, partner); 
     LOG.info("partner details updated for partner id {}", employeeId); 
     return new ResponseEntity<>(partner.getId(), HttpStatus.OK); 
    } 

    @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: BAD_REQUEST 
    @ExceptionHandler({EmployeePartnerExistsException.class, EmployeePartnerNotFoundException.class}) 
    public ResponseEntity<?> employeePartnerError(Exception ex) { 
     LOG.error(ex.getMessage()); 
     return new ResponseEntity<Object>(new ErrorResponse(400, ex.getMessage()), HttpStatus.OK); 
    } 

    @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: BAD_REQUEST 
    @ExceptionHandler(IllegalArgumentException.class) 
    public ResponseEntity<?> validationError(Exception ex) { 
     LOG.error(ex.getMessage()); 
     return new ResponseEntity<Object>(new ErrorResponse(400, ex.getMessage()), HttpStatus.OK); 
    } 

    @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: FORBIDDEN 
    @ExceptionHandler(ReadOperationDeniedException.class) 
    public ResponseEntity<?> forbidden(Exception ex) { 
     LOG.error("User doesn't have permissions to amend employee's details"); 
     return new ResponseEntity<Object>(new ErrorResponse(403, "User doesn't have permissions to amend employee's details"), HttpStatus.OK); 
    } 

    @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: INTERNAL_SERVER_ERROR 
    @ExceptionHandler(Exception.class) 
    public ResponseEntity<?> unspecifiedError(Exception ex) { 
     LOG.error("User doesn't have permissions to amend employee's details"); 
     return new ResponseEntity<Object>(new ErrorResponse(500, "Something went wrong while editing employee's details"), HttpStatus.OK); 
    } 
+1

ControllerAdvice比在同一控制器中定义异常处理程序要好。因为ExceptionHandler注释方法只对该特定控制器有效,而不是整个应用程序的全局。当然,将它添加到每个控制器使其不适合用于一般的异常处理机制。 –

+1

只需查看http://www.baeldung.com/exception-handling-for-rest-with-spring –