{"record":{"id":"c0ef87ad0c6d23fd","repo":"yudaocode/SpringBoot-Labs","slug":"error-c0ef87","errorCode":null,"errorMessage":"没有粗面鱼丸","messagePattern":"没有粗面鱼丸","errorType":"http","errorClass":"NullPointerException","httpStatus":500,"severity":"error","filePath":"lab-27/lab-27-webflux-02/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java","lineNumber":101,"sourceCode":"     * 获得指定用户编号的用户\n     *\n     * @param id 用户编号\n     * @return 用户\n     */\n    @GetMapping(\"/get4\")\n    public CommonResult<UserVO> get4(@RequestParam(\"id\") Integer id) {\n        // 查询用户\n        UserVO user = new UserVO().setId(id).setUsername(\"username:\" + id);\n        // 返回\n        return CommonResult.success(user);\n    }\n\n    /**\n     * 测试抛出 NullPointerException 异常\n     */\n    @GetMapping(\"/exception-01\")\n    public UserVO exception01() {\n        throw new NullPointerException(\"没有粗面鱼丸\");\n    }\n\n    /**\n     * 测试抛出 ServiceException 异常\n     */\n    @GetMapping(\"/exception-02\")\n    public UserVO exception02() {\n        throw new ServiceException(ServiceExceptionEnum.USER_NOT_FOUND);\n    }\n\n//    @PostMapping(value = \"/add\",\n//            // ↓ 增加 \"application/xml\"、\"application/json\" ，针对 Content-Type 请求头\n//            consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},\n//            // ↓ 增加 \"application/xml\"、\"application/json\" ，针对 Accept 请求头\n//            produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}\n//    )\n\n    @PostMapping(value = \"/add\",","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/yudaocode/SpringBoot-Labs/blob/6c12efaed06d12907a0f40dd2ad1f7020aec8798/lab-27/lab-27-webflux-02/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java#L83-L119","documentation":"The WebFlux counterpart of the MVC NPE demo: GET /user/exception-01 in a Spring WebFlux (reactive) application throws NullPointerException('没有粗面鱼丸') directly from the controller method. Because the method returns a plain UserVO (not a reactive type), WebFlux still funnels the thrown exception into the error channel, where an @ExceptionHandler in a @ControllerAdvice (or the default WebExceptionHandler chain, e.g. DefaultErrorWebExceptionHandler) renders it — by default as a JSON {timestamp, path, status:500, error, message} body.","triggerScenarios":"Calling GET /user/exception-01 on the WebFlux server (default port 8080 unless configured). The throw is unconditional.","commonSituations":"Used to verify exception handling in reactive stacks. Real-world analogue: a blocking/unintentional NPE inside a WebFlux controller; if it happens inside a reactive operator (map/flatMap lambda) instead of the controller body, the same error surfaces via onError propagation, and the stack trace shows operator assembly points, which confuses developers migrating from MVC.","solutions":["Treat it as demo code: call it only to confirm your error WebExceptionHandler/@ControllerAdvice output shape.","Register an @ExceptionHandler(NullPointerException.class) (or Exception-level) in a @ControllerAdvice so clients get your unified CommonResult JSON instead of the default error attributes.","If this NPE appears unintentionally in WebFlux, remember the stack trace may point to reactor internals — enable checkpoint() or onOperatorDebug to locate the lambda that threw.","Avoid throwing from controller bodies in real reactive code; return Mono.error(...) so the error travels the reactive chain predictably."],"exampleFix":"// before (throwing imperatively in WebFlux)\n@GetMapping(\"/exception-01\")\npublic UserVO exception01() {\n    throw new NullPointerException(\"没有粗面鱼丸\");\n}\n\n// after (route the error through the reactive chain + unified handler)\n@GetMapping(\"/exception-01\")\npublic Mono<UserVO> exception01() {\n    return Mono.error(new NullPointerException(\"没有粗面鱼丸\"));\n}\n\n@RestControllerAdvice\nclass GlobalExceptionHandler {\n    @ExceptionHandler(NullPointerException.class)\n    CommonResult<?> npe(NullPointerException ex) { return CommonResult.error(...); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// WebFlux: handle in a @ControllerAdvice, or inside the chain with onErrorResume:\n@GetMapping(\"/exception-01\")\npublic Mono<UserVO> exception01() {\n    return Mono.error(new NullPointerException(\"没有粗面鱼丸\"))\n               .onErrorResume(ex -> Mono.empty()); // or map to CommonResult","preventionTips":["Prefer Mono.error/Flux.error over throwing inside reactive controllers.","Register error handling once via @ControllerAdvice or ErrorWebExceptionHandler instead of per-endpoint.","Use checkpoint()/Hooks.onOperatorDebug() to get actionable stack traces for errors born inside operators."],"tags":["webflux","reactive","npe","tutorial","deliberate-throw","exception-handler"],"backgroundTag":null,"analyzedSha":"6c12efaed06d12907a0f40dd2ad1f7020aec8798","analyzedAt":"2026-08-14T13:06:31.500Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}