{"record":{"id":"98f71750ec92fd6e","repo":"yudaocode/SpringBoot-Labs","slug":"id-98f717","errorCode":null,"errorMessage":"id 参数不允许为空","messagePattern":"id 参数不允许为空","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":200,"severity":"info","filePath":"labx-04-spring-cloud-alibaba-sentinel/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java","lineNumber":69,"sourceCode":"            return \"执行成功\";\n        } catch (BlockException ex) { // <3>\n            return \"被拒绝\";\n        } finally {\n            // <4> 释放资源\n            if (entry != null) {\n                entry.exit();\n            }\n        }\n    }\n\n    // 测试「Sentinel @SentinelResource 注解」\n    @GetMapping(\"/annotations_demo\")\n    @SentinelResource(value = \"annotations_demo_resource\",\n            blockHandler = \"blockHandler\",\n            fallback = \"fallback\")\n    public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException {\n        if (id == null) {\n            throw new IllegalArgumentException(\"id 参数不允许为空\");\n        }\n        return \"success...\";\n    }\n\n    // BlockHandler 处理函数，参数最后多一个 BlockException，其余与原函数一致.\n    public String blockHandler(Integer id, BlockException ex) {\n        return \"block：\" + ex.getClass().getSimpleName();\n    }\n\n    // Fallback 处理函数，函数签名与原函数一致或加一个 Throwable 类型的参数.\n    public String fallback(Integer id, Throwable throwable) {\n        return \"fallback：\" + throwable.getMessage();\n    }\n\n}\n","sourceCodeStart":51,"sourceCodeEnd":85,"githubUrl":"https://github.com/yudaocode/SpringBoot-Labs/blob/6c12efaed06d12907a0f40dd2ad1f7020aec8798/labx-04-spring-cloud-alibaba-sentinel/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java#L51-L85","documentation":"Intentional validation exception in the Sentinel lab's base demo01 provider. The @SentinelResource-annotated /annotations_demo endpoint throws IllegalArgumentException when the optional id parameter is null; Sentinel's annotation aspect catches it and invokes the configured fallback, whose signature ends with a Throwable parameter. The endpoint therefore returns 'fallback：id 参数不允许为空' with HTTP 200 — the demo shows how fallback absorbs business exceptions.","triggerScenarios":"GET /demo/annotations_demo without ?id=... — id binds to null, the guard throws, fallback returns the message.","commonSituations":"First run of the demo without reading the tutorial's expected curl command; verifying Sentinel dependencies (sentinel-annotation-aspect bean) and using this response as evidence the aspect is active; mistaking the fallback body for an error status.","solutions":["Append ?id=1 to the request to get 'success...'.","Recognize 'fallback：id 参数不允许为空' as correct fallback behavior for this lab.","Make the parameter required if you want missing values rejected as 400 by Spring MVC."],"exampleFix":"// before\npublic String annotationsDemo(@RequestParam(required = false) Integer id) {\n    if (id == null) { throw new IllegalArgumentException(\"id 参数不允许为空\"); }\n    return \"success...\";\n}\n\n// after\npublic String annotationsDemo(@RequestParam Integer id) {\n    return \"success...\";\n}","handlingStrategy":"try-catch","validationCode":"// GET /demo/annotations_demo?id=1 avoids the throw entirely\nif (queryParams.containsKey(\"id\")) { /* safe to call */ }","typeGuard":null,"tryCatchPattern":"// In your own non-Sentinel wrapper around this endpoint:\ntry {\n    result = client.get(\"/annotations_demo?id=\" + id);\n} catch (HttpStatusCodeException e) {\n    log.warn(\"annotations_demo failed: {}\", e.getResponseBodyAsString());\n}","preventionTips":["Pass id explicitly; never rely on the optional default (there is none).","Use the fallback body as the demo's expected negative-path output.","Validate inputs at the controller boundary for real services."],"tags":["sentinel","spring-cloud-alibaba","tutorial-demo","fallback","validation"],"backgroundTag":null,"analyzedSha":"6c12efaed06d12907a0f40dd2ad1f7020aec8798","analyzedAt":"2026-08-14T13:06:31.500Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}