You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在catch语句内调用抛出AppException的函数时调试器显示未处理用户异常?

为什么抛出自定义AppException时调试器显示“Unhandled user exception”?

我定义了一个会抛出自定义AppException的getRefreshToken函数,该函数在RefreshToken方法的try块中被调用。当该异常抛出时,调试器显示“Unhandled user exception”提示,请问这是为什么?


自定义异常抛出函数 getRefreshToken

private (RefreshToken, Account) getRefreshToken(string token)
{
    var account = _context.Accounts.Include(x => x.RefreshTokens).SingleOrDefault(u => u.RefreshTokens.Any(t => t.Token == token));
    //var account = _context.Accounts.SingleOrDefault(u => u.RefreshTokens.Any(t => t.Token == token));
    if (account == null)
    {
        Console.WriteLine("Exception thrown");
        throw new AppException("Invalid account for token" + token);
    }
    var refreshToken = account.RefreshTokens.Single(x => x.Token == token);
    if (!refreshToken.IsActive)
    {
        Console.WriteLine("Exception thrown");
        throw new AppException("Invalid token:" + token);
    }
    return (refreshToken, account);
}

调用该函数的 RefreshToken 方法

public AuthenticateResponse RefreshToken(string token, string ipAddress)
{
    log.Info("RefreshToken before locking");
    Monitor.Enter(lockObject);

    using (IDbContextTransaction transaction = _context.Database.BeginTransaction())
    {
        try
        {
            var (refreshToken, account) = getRefreshToken(token);

        }
        catch 
        {
            transaction.Rollback();
            Console.WriteLine(Thread.CurrentThread.Name + "Error occurred.");
            log.Error(Thread.CurrentThread.Name + "Error occurred in RefreshToken:");
            throw;
        }
        finally
        {
            Monitor.Exit(lockObject);
            log.Info("RefreshToken after locking");
        }
    }
}

问题原因

你的RefreshToken方法虽然捕获了异常,但在catch块最后执行了throw;语句——这个语句会重新抛出当前捕获的异常,而这个重新抛出的异常并没有被上层调用者处理,所以调试器会提示“Unhandled user exception”。

具体流程:

  • getRefreshToken抛出AppException,被RefreshToken的catch块捕获
  • catch块仅执行了回滚事务、打印日志操作,没有处理异常,而是用throw;将异常重新抛出
  • 如果调用RefreshToken的上层代码没有额外的try/catch块来处理这个异常,它就会成为未处理的异常,触发调试器的提示

另外还有一个潜在风险:如果Monitor.Enter(lockObject)执行后,_context.Database.BeginTransaction()抛出异常,代码会直接跳出using块和try块,不会进入finally执行Monitor.Exit,导致锁泄漏。建议改用lock语句(自动处理锁的释放),或者把Monitor.Enter移到try块内部。


内容的提问来源于stack exchange,提问作者janci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:15:36