dromara/Sa-Token · error · SaTokenException

10002

10002

Error message

未能获取对应StpLogic,type=" + loginType

What it means

Thrown by Sa-Token's JFinal plugin (SaTokenActionHandler) when a controller finishes with a ForwardActionRender whose target action URL is identical to the URL currently being handled. The handler would recursively call handle(actionUrl, ...) forever, so it detects self-forwarding and fails fast instead of overflowing the stack.

Source

Thrown at sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java:356

			// isCreate=true时,自创建模式:自动创建并返回 
			if(isCreate) {
				synchronized (SaManager.class) {
					stpLogic = stpLogicMap.get(loginType);
					if(stpLogic == null) {
						stpLogic = SaStrategy.instance.createStpLogic.apply(loginType);
					}
				}
			} 
			// isCreate=false时,严格校验模式:抛出异常 
			else {
				/*
				 * 此时有两种情况会造成 StpLogic == null 
				 * 1. loginType拼写错误,请改正 (建议使用常量) 
				 * 2. 自定义StpUtil尚未初始化(静态类中的属性至少一次调用后才会初始化),解决方法两种
				 * 		(1) 从main方法里调用一次
				 * 		(2) 在自定义StpUtil类加上类似 @Component 的注解让容器启动时扫描到自动初始化 
				 */
				throw new SaTokenException("未能获取对应StpLogic,type="+ loginType).setCode(SaErrorCode.CODE_10002);
			}
		}
		
		// 返回 
		return stpLogic;
	}
	
}

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Find the ForwardActionRender being created (controller action or interceptor) and make its action URL different from the incoming target
  2. If the forward target is configurable, fix the route/config value so it does not resolve to the same action
  3. Guard before forwarding: if (actionUrl.equals(target)) return a 404/error render instead of forwarding
  4. Add a unit test asserting the forward target never equals the original route for your default/error paths

Example fix

// before
public void index() {
    render(new ForwardActionRender(getPara("to"))); // ?to=/index -> self-forward
}

// after
public void index() {
    String to = getPara("to");
    if (to == null || to.equals("/index")) {
        renderError(404);
        return;
    }
    render(new ForwardActionRender(to));
}
Defensive patterns

Strategy: validation

Validate before calling

String target = request.getRequestURI();
String actionUrl = forwardRender.getActionUrl();
if (target.equals(actionUrl)) {
    // refuse to self-forward; render an error instead
    controller.renderError(404);
    return;
}
handle(actionUrl, request, response, isHandled);

Try / catch

catch (RuntimeException e) when message contains 'forward action url is the same as before': log target + actionUrl, render 404/500 once, do NOT re-invoke the forward

Prevention

When it happens

Trigger: A JFinal controller executes render(...) with a ForwardActionRender (e.g. controller.forwardAction or an interceptor that forwards) where getActionUrl() returns exactly the same target string the handler is already processing; typically the result of string concatenation or a config value that points the route back at itself.

Common situations: Route config points a path to a controller that forwards back to the same path; a default-route fallback forwards '/' to a URL that is itself '/'; typos in a forward target that happen to equal the current URL; refactoring that left a self-referencing forward.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/64183505dfcfbb5f. Report an issue: GitHub.