Unified Exception Handling in Spring Cloud with @RestControllerAdvice
This article demonstrates how to consolidate exception handling in a Spring Cloud microservice using @RestControllerAdvice, @Slf4j, and @ExceptionHandler, defines a unified error code enum, and provides test scenarios with sample code and API requests.
Unified Exception Handling
1. Background
When writing code we often add try‑catch blocks inside methods, which leads to a lot of duplicated code; therefore we can integrate a unified exception handling mechanism to improve code structure.
2. Custom Exception Handler Class
Add the unified exception handling class annotation @RestControllerAdvice Add logging annotation @Slf4j Add exception handling method annotation
@ExceptionHandler package com.jackson0714.passjava.question.exception;
/*
* Centralized handling of all exceptions
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.jackson0714.passjava.question.controller")
public class PassjavaExceptionControllerAdvice {
@ResponseBody
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException e) {
log.error("Validation error: {}, exception type: {}", e.getMessage(), e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach(fieldError -> {
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(), BizCodeEnum.VALID_EXCEPTION.getMsg())
.put("data", errorMap);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
log.error("Unknown exception: {}, exception type: {}", throwable.getMessage(), throwable.getClass());
return R.error(BizCodeEnum.UNKNOWN_EXCEPTION.getCode(), BizCodeEnum.UNKNOWN_EXCEPTION.getMsg());
}
}3. Recommended System Error Codes
1. Error code and message definition
Length of error code: 5 digits
First two digits: business scenario
Last three digits: specific error
10: General business
001: Parameter format validation error (10001)
11: Member business
12: Question business
13: Content business
14: Learning business2. Error code enum class
Defines two exception enums: unknown system exception and parameter format validation failure.
package com.jackson0714.common.exception;
public enum BizCodeEnum {
UNKNOWN_EXCEPTION(10000, "System unknown exception"),
VALID_EXCEPTION(10001, "Parameter format validation failed");
private int code;
private String msg;
BizCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() { return code; }
public String getMsg() { return msg; }
}4. Test Code
Test scenario 1: Validate that the parameter displayOrder must be a positive integer; if it is not, an exception is thrown.
1. Add validation annotation @Positive on the entity field.
/**
* Order
*/
@Positive
private Integer displayOrder;2. Add a save method in the controller and annotate the parameter with @Valid.
/**
* Save
*/
@RequestMapping("/save")
public R save(@Valid @RequestBody QuestionEntity question) {
questionService.save(question);
return R.ok();
}Test with Postman:
Request URL:
http://192.168.10.160:8060/api/question/v1/admin/question/saveRequest body:
{
"displayOrder": 0.2
}Response:
{
"msg": "Parameter format validation failed",
"code": 10001,
"data": {
"displayOrder": "must be a positive number"
}
}Test scenario 2: Directly thrown exceptions in code can also be handled by the unified handler.
1. Add an info method in the controller that throws Exception.
/**
* Info
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id) throws Exception {
QuestionEntity question = questionService.getById(id);
throw new Exception("test");
// return R.ok().put("question", question);
}Test with Postman (same URL as above) returns:
{
"msg": "System unknown exception",
"code": 10000
}This proves that the @ExceptionHandler for Throwable is invoked:
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
return R.error(BizCodeEnum.UNKNOWN_EXCEPTION.getCode(), BizCodeEnum.UNKNOWN_EXCEPTION.getMsg());
}5. Code Repository
Source code is available at https://github.com/Jackson0714/PassJava-Platform
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Wukong Talks Architecture
Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
