记录一次生产递归死循环问题

193 阅读1分钟

一、背景

客户在第一次打开,或者切换用户第一次登录SAAS时,发现无法登陆saas,页面空白。需要反复刷新才OK。 但是如果不是第一次登录,一切正常。

二、问题排查

主要是查看报错记录,定位问题

中间因为日志不清晰,看不出堆栈信息,还在代码中补充了打印堆栈日志:logger.error(traceback.format_exc())

image.png

image.png

截屏2025-01-07 14.01.24.png

三、原因分析

从上面的异常信息来看,可以推断出,在ComponentAPI中,self.client.request方法在循环递归调用,抛出了递归超过深度的异常maximum recursion depth exceeded in comparison

然后顺着报错位置,往上链路追查,发现是在做用户验证的时候,出现了循环递归,代码如下:

def authenticate(self, request):
    xxx
    session_key = request.session.session_key
    logger.error(f"登录authenticate, session_key: {session_key}")
    if session_key:
        # 确认 cookie 中的 ticket 和 cache 中的是否一致
        xxx
        if is_match and request.user.is_authenticated:
            return request.user

    user = auth.authenticate(request=request, bk_token=bk_token)
    logger.error(f"登录authenticate, user: {user},request.user: {request.user}")
    xxxx

    if user is not None and request.user.is_authenticated:
        # 登录成功,重新调用自身函数,即可退出
        cache.set(session_key, {"bk_token": bk_token}, settings.LOGIN_CACHE_EXPIRED)
        logger.error("登录authenticate,重新调用自身函数,即可退出")
        return self.authenticate(request)
    return user

当session_key为None时,这段代码就会陷入死循环

四、解决措施

定位到根因,就可以针对性解决 解决措施:当session_key为None时,加一个判断,重新获取session_key即可