{"record":{"id":"f61d3d3c7b54d4a9","repo":"dromara/Sa-Token","slug":"10032","errorCode":"10032","errorMessage":"注册的侦听器不可以为空","messagePattern":"注册的侦听器不可以为空","errorType":"validation","errorClass":"SaTokenException","httpStatus":null,"severity":"error","filePath":"sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java","lineNumber":72,"sourceCode":"\n\t/**\n\t * 重置侦听器集合\n\t * @param listenerList / \n\t */\n\tpublic static void setListenerList(List<SaTokenListener> listenerList) {\n\t\tif(listenerList == null) {\n\t\t\tthrow new SaTokenException(\"重置的侦听器集合不可以为空\").setCode(SaErrorCode.CODE_10031);\n\t\t}\n\t\tSaTokenEventCenter.listenerList = listenerList;\n\t}\n\n\t/**\n\t * 注册一个侦听器 \n\t * @param listener / \n\t */\n\tpublic static void registerListener(SaTokenListener listener) {\n\t\tif(listener == null) {\n\t\t\tthrow new SaTokenException(\"注册的侦听器不可以为空\").setCode(SaErrorCode.CODE_10032);\n\t\t}\n\t\tlistenerList.add(listener);\n\t}\n\n\t/**\n\t * 注册一组侦听器 \n\t * @param listenerList / \n\t */\n\tpublic static void registerListenerList(List<SaTokenListener> listenerList) {\n\t\tif(listenerList == null) {\n\t\t\tthrow new SaTokenException(\"注册的侦听器集合不可以为空\").setCode(SaErrorCode.CODE_10031);\n\t\t}\n\t\tfor (SaTokenListener listener : listenerList) {\n\t\t\tif(listener == null) {\n\t\t\t\tthrow new SaTokenException(\"注册的侦听器不可以为空\").setCode(SaErrorCode.CODE_10032);\n\t\t\t}\n\t\t}\n\t\tSaTokenEventCenter.listenerList.addAll(listenerList);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java#L54-L90","documentation":"SaTokenException (code 10032) thrown by SaTokenEventCenter.registerListener(SaTokenListener) when the listener argument is null. A null listener would throw NPE later during every event broadcast, so registration rejects it up front.","triggerScenarios":"Calling SaTokenEventCenter.registerListener(null) — commonly from a DI container or startup hook where the listener bean failed to instantiate (returned null) or a conditionally created listener was null.","commonSituations":"Registering a bean obtained from a context that has not initialized it yet; conditional listener creation (if (useCustom) listener = new ... else null) then unconditional registration; framework integration code looping over a list containing nulls without filtering.","solutions":["Null-check before registering: if (listener != null) SaTokenEventCenter.registerListener(listener)","Fix the bean/provider so it never yields null (fail bean creation loudly instead)","Filter nulls when bulk-registering: listeners.stream().filter(Objects::nonNull).forEach(SaTokenEventCenter::registerListener)"],"exampleFix":"// before\nSaTokenEventCenter.registerListener(context.getBean(\"myListener\", SaTokenListener.class)); // bean missing -> null -> 10032\n\n// after\nSaTokenListener l = context.getBeanProvider(SaTokenListener.class).getIfAvailable();\nif (l != null) SaTokenEventCenter.registerListener(l);","handlingStrategy":"validation","validationCode":"if (listener != null) {\n    SaTokenEventCenter.registerListener(listener);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Null-check listener references (especially DI-provided beans) before registering","Fail bean construction loudly when a required listener cannot be created","Filter nulls when registering from collections"],"tags":["event-listener","validation","null-safety","sa-token"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}