Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ErrorEntryFreeException:current entry in context: </error> #1531

Closed
missfmaster opened this issue Jun 8, 2020 · 8 comments
Closed

ErrorEntryFreeException:current entry in context: </error> #1531

missfmaster opened this issue Jun 8, 2020 · 8 comments
Labels
area/integrations Issues or PRs related to integrations with open-source components kind/bug Category issues or prs related to bug.

Comments

@missfmaster
Copy link

springboot在发生错误时,出现了问题。
com.alibaba.csp.sentinel.ErrorEntryFreeException: The order of entry exit can't be paired with the order of entry, current entry in context: </error>, but expected: </xxx>
当请求/xxx的时候,显式抛出了异常,然后进入/error,然后就发生了以上问题。
版本1.7.1,starter版本2.2.1。

@cdfive
Copy link
Collaborator

cdfive commented Jun 8, 2020

It seems that spring-cloud-starter-alibaba-sentinel 2.2.1.RELEASE use sentinel 1.7.2.

I tried to throw RuntimeException in controller explicitly, the /error will be entered indeed, but didn't get the ErrorEntryFreeException.

Any other informaton?

May refer to #1392 and #1482

@cdfive cdfive added the area/integrations Issues or PRs related to integrations with open-source components label Jun 8, 2020
@missfmaster
Copy link
Author

missfmaster commented Jun 9, 2020

我强制升级到了1.7.2,但是还是产生此问题,再具体介绍下情况:

1、请求"/post"控制器,然后显式抛出RuntimeException;
2、异常被异常拦截器拦截,返回ModelAndView,view名称被设置成"/error";
3、然后请求被转发到了"/error",重新进入DispatcherServlet;
4、于是重新运行了"SentinelWebInterceptor(AbstractSentinelInterceptor)",创建了新的"Entry";
5、但是放入request中时似乎出现问题?此处判断如果已经存在,则不再设置,打印了一条警告;
但是创建新的"Entry"时,将Context的curEntry设置为新创建的"Entry",
所以导致在退出清理时,CtEntry的exitForContext方法中,从request中获取的Entry和context.getCurEntry()中获取的必然不相等,则进入如下代码:
if (context.getCurEntry() != this) {
                String curEntryNameInContext = context.getCurEntry() == null ? null : context.getCurEntry().getResourceWrapper().getName();
                // Clean previous call stack.
                CtEntry e = (CtEntry)context.getCurEntry();
                while (e != null) {
                    e.exit(count, args);
                    e = (CtEntry)e.parent;
                }
                String errorMessage = String.format("The order of entry exit can't be paired with the order of entry"
                    + ", current entry in context: <%s>, but expected: <%s>", curEntryNameInContext, resourceWrapper.getName());
                throw new ErrorEntryFreeException(errorMessage);
            } 
...
所以导致了异常。。。
此处是别有用意?还是需要单独设置?还有本身bug?

@cdfive
Copy link
Collaborator

cdfive commented Jun 9, 2020

是的,你描述的很详细。
2、异常被异常拦截器拦截,返回ModelAndView,view名称被设置成"/error";
是用了统一的异常处理吗?能否贴下异常处理代码。

本机调试发现:
如果没有异常拦截器,在进第3步之前,会进AbstractSentinelInterceptor#afterCompletion方法,里面traceExceptionAndExitremoveEntryInRequest会将Entry exit并且从request属性中删除。
这样当再进3步时能正常创建Entry并放入request中,不会出现ErrorEntryFreeException。

PR #1533 尝试优化这里的逻辑,如果request中已有Entry了,不创建新的Entry,这样Entry的entry/exit就能匹配,避免ErrorEntryFreeException。

@missfmaster
Copy link
Author

嗯,谢谢回答。
异常拦截器是在做统一处理,记录了日志,并设置了转发,关键代码修剪后类似于这样(这并不重要):

ModelAndView mv = new ModelAndView();
mv.setViewName("/error");
return mv;

由于返回了ModelAndView,所以,在DispatcherServlet.processDispatchResult方法进行forword时,重新执行了mappedHandler.applyPreHandle,导致了在所有的triggerAfterCompletion执行之前,Entry的再次被创建。。。
问题已经明确,可以暂时添加优先级更高的异常拦截器退出entry,或者等待下个版本的优化。

@taikeung
Copy link

taikeung commented Jul 8, 2020

这个bug需要怎么去规避呢?

@cdfive
Copy link
Collaborator

cdfive commented Aug 15, 2020

@taikeung

registry.addInterceptor(new SentinelWebInterceptor(config)).addPathPatterns("/**").excludePathPatterns(xxx);

可以排除某些特殊的路径,比如确定不需要限流的。

欢迎来review和讨论这个PR #1533

@missfmaster
Copy link
Author

额,旧事重提;
我记得Entry里边好像有个父子级的概念,而且也维护了父子级的关系,但是关闭时,为啥就不使用这个关系了哪。。。

@sczyh30
Copy link
Member

sczyh30 commented Oct 29, 2020

Fixed in #1533 in 1.8.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/integrations Issues or PRs related to integrations with open-source components kind/bug Category issues or prs related to bug.
Projects
None yet
Development

No branches or pull requests

4 participants