2017-08-02 54 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 –