{"record":{"id":"1b257c93e7139482","repo":"qiurunze123/miaosha","slug":"error","errorCode":null,"errorMessage":"用户名已经存在!","messagePattern":"用户名已经存在!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/LogininfoServiceImpl.java","lineNumber":75,"sourceCode":"            //MD5(MD5(password)+salt)\n            logininfo.setPassword(MD5Utils.formPassToDBPass(password, salt));\n            logininfo.setState(Constants.STATE_NORMAL);\n            logininfo.setUserType(Constants.USERTYPE_NORMAL);\n            logininfo.setRegisterDate(new Date());\n            logininfo.setLastLoginDate(new Date());\n            logininfo.setSalt(salt);\n            this.loginInfoMapper.insert(logininfo);\n\n            //初始化一个account\n            Account account = Account.empty(logininfo.getId());\n            accountMapper.insert(account);\n\n\n            //初始化一个Userinfo\n            Userinfo userinfo = Userinfo.empty(logininfo.getId());\n            int result = this.userinfoMapper.insert(userinfo);\n        } else {\n            throw new RuntimeException(\"用户名已经存在!\");\n        }\n    }\n\n    @Override\n    public boolean checkUsername(String name, int userType) {\n        return this.loginInfoMapper.getCountByNickname(name, userType) <= 0;\n    }\n\n    @Override\n    public ResultGeekQ<Logininfo> login(String name, String password, int userType, String ip) {\n        ResultGeekQ<Logininfo> resultGeekQ = ResultGeekQ.build();\n\n        try {\n            IpLog log = new IpLog(name, new Date(), ip, userType, null);\n            Logininfo logininfo = loginInfoMapper.getLoginInfoByNickname(name, Constants.USERTYPE_NORMAL);\n            String salt = logininfo.getSalt();\n            Logininfo current = this.loginInfoMapper.login(name,\n                    MD5Utils.formPassToDBPass(password, salt), userType);","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/qiurunze123/miaosha/blob/e58017658e549b63fc4db2160d2325ccd7f8435b/miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/LogininfoServiceImpl.java#L57-L93","documentation":"Thrown by LogininfoServiceImpl.register() when the supplied username already exists in the logininfo table. The method queries loginInfoMapper.getCountByNickname(username, USERTYPE_NORMAL) and, if count > 0, raises a raw RuntimeException with the literal message '用户名已经存在!' (Username already exists). Unlike the rest of the codebase, this uses java.lang.RuntimeException directly instead of the project's GlobleException, so the GlobalExceptionHandler will not map it to a structured ResultStatus code — it falls through to a generic 500.","triggerScenarios":"POST to the admin register endpoint with a nickname that already has a row in logininfo where userType = USERTYPE_NORMAL. Two concurrent register calls with the same nickname can also trigger it because there is no DB unique constraint enforced in the insert path shown. Calling register() a second time with the same value always reproduces it.","commonSituations":"Registering a duplicate user during integration tests without cleaning the table; missing unique-constraint on the nickname column so a race condition lets two inserts through; front-end failing to call checkUsername() before submit; automated load tests reusing the same account name.","solutions":["Call checkUsername(name, userType) before invoking register(); it returns true when the nickname is free (count <= 0).","Add a unique database index on (nickname, userType) in the logininfo table so duplicates are rejected at the DB level even under concurrency.","Replace the raw RuntimeException with GlobleException(RESIGETER_NICKNAMEEXIST) so the error is caught by GlobalExceptionHandler and returned as a structured code 200003 instead of an HTTP 500.","Return a ResultGeekQ error from register() instead of throwing, matching the pattern used by login()."],"exampleFix":"// before\n} else {\n    throw new RuntimeException(\"用户名已经存在!\");\n}\n\n// after\n} else {\n    throw new GlobleException(ResultStatus.RESIGETER_NICKNAMEEXIST);\n}","handlingStrategy":"validation","validationCode":"// Check before calling register()\nboolean isAvailable = logininfoService.checkUsername(username, Constants.USERTYPE_NORMAL);\nif (!isAvailable) {\n    return ResultGeekQ.error(ResultStatus.RESIGETER_NICKNAMEEXIST);\n}\nlogininfoService.register(username, password);","typeGuard":null,"tryCatchPattern":"// Catch raw RuntimeException since register() does not use GlobleException\ntry {\n    logininfoService.register(username, password);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"用户名已经存在\")) {\n        return ResultGeekQ.error(ResultStatus.RESIGETER_NICKNAMEEXIST);\n    }\n    throw e;\n}","preventionTips":["Always call checkUsername() before register() in the controller layer.","Add a unique DB constraint on (nickname, userType) to prevent race conditions.","Use the project's GlobleException instead of raw RuntimeException for consistent error handling."],"tags":["authentication","registration","duplicate","admin","runtime-exception"],"backgroundTag":null,"analyzedSha":"e58017658e549b63fc4db2160d2325ccd7f8435b","analyzedAt":"2026-08-14T05:22:03.691Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}