{"record":{"id":"427615e9114f6383","repo":"qiurunze123/miaosha","slug":"10001-427615","errorCode":"10001","errorMessage":"系统错误","messagePattern":"系统错误","errorType":"exception","errorClass":"GlobleException","httpStatus":null,"severity":"error","filePath":"miaosha-v2/miaosha-service/src/main/java/com/geekq/miaosha/service/MiaoShaUserService.java","lineNumber":132,"sourceCode":"            MiaoshaUser user = miaoShaUserMapper.getByNickname(miaoShaUser.getNickname());\n            if (user == null) {\n                return false;\n            }\n\n\n            //生成cookie 将session返回游览器 分布式session\n            String token = UUIDUtil.uuid();\n            addCookie(response, token, user);\n        } catch (Exception e) {\n            logger.error(\"注册失败\", e);\n            return false;\n        }\n        return true;\n    }\n\n    public boolean login(HttpServletResponse response, LoginVo loginVo) {\n        if (loginVo == null) {\n            throw new GlobleException(SYSTEM_ERROR);\n        }\n\n        String mobile = loginVo.getNickname();\n        String password = loginVo.getPassword();\n        MiaoshaUser user = getByNickName(mobile);\n        if (user == null) {\n            throw new GlobleException(MOBILE_NOT_EXIST);\n        }\n\n        String dbPass = user.getPassword();\n        String saltDb = user.getSalt();\n        String calcPass = MD5Utils.formPassToDBPass(password, saltDb);\n        if (!calcPass.equals(dbPass)) {\n            throw new GlobleException(PASSWORD_ERROR);\n        }\n        //生成cookie 将session返回游览器 分布式session\n        String token = UUIDUtil.uuid();\n        addCookie(response, token, user);","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/qiurunze123/miaosha/blob/e58017658e549b63fc4db2160d2325ccd7f8435b/miaosha-v2/miaosha-service/src/main/java/com/geekq/miaosha/service/MiaoShaUserService.java#L114-L150","documentation":"Thrown by MiaoShaUserService.login() (miaosha-v2) when the LoginVo argument is null. Maps to ResultStatus.SYSTEM_ERROR (code 10001, '系统错误'). This is a top-of-method null guard identical in purpose to v1's error 2. In v2, the LoginVo field is accessed via getNickname() instead of getMobile(), but the null check fires before any field access.","triggerScenarios":"Calling login(response, null) from a controller where the LoginVo failed to bind, or from test code that did not construct the object. The controller likely uses @RequestBody or @ModelAttribute without @Valid.","commonSituations":"Malformed JSON login body that Spring cannot deserialize into LoginVo; controller passes the raw null through; integration test omitting the LoginVo argument.","solutions":["Add @Valid on the LoginVo controller parameter so Spring rejects null/malformed bodies at the web layer.","Return a 400 from the controller when loginVo is null rather than invoking the service.","Always construct LoginVo with setNickname() and setPassword() in tests."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Controller-layer guard (v2)\nif (loginVo == null) {\n    return ResultGeekQ.error(ResultStatus.PARAM_ERROR);\n}\nreturn userService.login(response, loginVo);","typeGuard":"// Ensure LoginVo is non-null with required fields (v2 uses getNickname)\nif (loginVo == null || loginVo.getNickname() == null || loginVo.getPassword() == null) {\n    throw new IllegalArgumentException(\"LoginVo and its fields must not be null\");\n}","tryCatchPattern":"try {\n    userService.login(response, loginVo);\n} catch (GlobleException e) {\n    if (e.getStatus() == ResultStatus.SYSTEM_ERROR) {\n        return ResultGeekQ.error(ResultStatus.PARAM_ERROR);\n    }\n    throw e;\n}","preventionTips":["Add @RequestBody @Valid on the LoginVo controller parameter.","Populate both nickname and password fields in tests.","Use @NotNull JSR-303 annotations on LoginVo fields."],"tags":["authentication","null-check","input-validation","miaosha-v2","system-error"],"backgroundTag":null,"analyzedSha":"e58017658e549b63fc4db2160d2325ccd7f8435b","analyzedAt":"2026-08-14T05:22:03.691Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}