yudaocode/SpringBoot-Labs · info · java.lang.IllegalArgumentException
id 参数不允许为空
Error message
id 参数不允许为空
What it means
Intentional validation exception in the Sentinel lab (actuator variant). The /annotations_demo endpoint is annotated with @SentinelResource(blockHandler=..., fallback=...); when the optional `id` request parameter is omitted it is null and the method throws IllegalArgumentException. Sentinel's sentinel-resource annotation interceptor catches it and routes it to the fallback method, so the HTTP response is normally 'fallback:id 参数不允许为空' (200), not a 500 — the lab exists to demonstrate fallback routing.
Source
Thrown at labx-04-spring-cloud-alibaba-sentinel/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java:69
return "执行成功";
} catch (BlockException ex) { // <3>
return "被拒绝";
} finally {
// <4> 释放资源
if (entry != null) {
entry.exit();
}
}
}
// 测试「Sentinel @SentinelResource 注解」
@GetMapping("/annotations_demo")
@SentinelResource(value = "annotations_demo_resource",
blockHandler = "blockHandler",
fallback = "fallback")
public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException {
if (id == null) {
throw new IllegalArgumentException("id 参数不允许为空");
}
return "success...";
}
// BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致.
public String blockHandler(Integer id, BlockException ex) {
return "block:" + ex.getClass().getSimpleName();
}
// Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
public String fallback(Integer id, Throwable throwable) {
return "fallback:" + throwable.getMessage();
}
}
View on GitHub (pinned to 6c12efaed0)
Solutions
- Add the parameter: GET /demo/annotations_demo?id=1 to see the normal 'success...' response.
- Read the 'fallback:...' body as proof the fallback path works — this is the demo's intended behavior.
- To return a proper 400 instead, make the param required (@RequestParam Integer id) so Spring rejects missing values before the method body runs.
Example fix
// before
@GetMapping("/annotations_demo")
public String annotationsDemo(@RequestParam(required = false) Integer id) {
if (id == null) {
throw new IllegalArgumentException("id 参数不允许为空");
}
...
}
// after — let Spring enforce presence; fallback stays for real business exceptions
@GetMapping("/annotations_demo")
public String annotationsDemo(@RequestParam Integer id) { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// Simply include the required parameter
// GET /demo/annotations_demo?id=1
if (idParam == null) { /* don't call; pass id */ } Try / catch
// Client side: the server already routes this to Sentinel fallback (HTTP 200 body 'fallback:...')
String body = restTemplate.getForObject(url + "/annotations_demo?id={id}", String.class, id);
if (body.startsWith("fallback:")) {
// handle degraded/business-failure path
} Prevention
- Always send ?id=... when calling annotated demo endpoints.
- Read Sentinel docs: fallback handles business exceptions, blockHandler handles BlockException.
- Make required parameters required in @RequestParam so Spring returns 400.
When it happens
Trigger: GET /demo/annotations_demo without the id query parameter. The IllegalArgumentException fires and the fallback function receives it as the Throwable parameter and returns its message.
Common situations: Testing the lab's fallback demo and forgetting the parameter; expecting a 400/validation error and being surprised by the 200 'fallback:...' body; confusing fallback (business exceptions) with blockHandler (flow/degrade BlockException) while learning Sentinel.
Related errors
AI-assisted analysis of yudaocode/SpringBoot-Labs@6c12efaed0 (2026-08-14).
Data as JSON: /api/errors/7dbad02ee3951223.
Report an issue: GitHub.