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

ADO.NET调用存储过程返回非零RETVAL时推荐抛出的异常类型

存储过程返回非零RETVAL时推荐抛出的异常类型

问题描述

我使用ADO.NET调用多个存储过程,其中大多数会返回RETVAL。目前当RETVAL非零时,我会抛出FaultException,但不确定这是否是最佳方案。我曾考虑过SqlException,但它没有公共构造函数,因此该方案不可行。请问当调用的存储过程返回非零值(表示执行失败)时,推荐抛出哪种异常?

现有遗留代码逻辑

public Employee GetEmployee(int id)
{
    string reason = nameof(GetEmployee);

    try
    {
        DataTable dataTable;
        long retVal = ExecuteCommand("ps_getemployee", CommandType.StoredProcedure, out dataTable,
            true,
            CreateSqlParameter(parameterName: "id", value: id));

        if (retVal != 0)
        {
            // 冗余代码:创建了3个新对象
            throw new FaultException<FaultExceptionSvc>(new FaultExceptionSvc(null, reason, message: retVal.ToString(), faultNbr: errorCode, skipFrames: 2), new FaultReason(reason));
            // 希望替换为更合适的异常类型
        }

        return CreateEmployeeFromRow(dataTable.Rows[0]);
    }
    catch (FaultException<FaultExceptionSvc>)
    {
        throw;
    }
    catch (Exception ex)
    {
        throw CreateFaultException(ex, reason);
    }
}

存储过程返回值片段

if @@error = 0
begin
    select @retval = 0
end
else
begin
    select @retval = -1
end

推荐方案

1. 自定义业务异常类

这是最灵活且符合.NET设计规范的方案,你可以创建一个继承自Exception的自定义异常,专门用于表示存储过程执行失败的业务错误:

public class StoredProcedureExecutionException : Exception
{
    public long ReturnValue { get; }
    public int ErrorCode { get; }

    public StoredProcedureExecutionException(long returnValue, int errorCode, string message, Exception innerException = null)
        : base(message, innerException)
    {
        ReturnValue = returnValue;
        ErrorCode = errorCode;
    }
}

替换原有抛出异常的代码:

if (retVal != 0)
{
    throw new StoredProcedureExecutionException(retVal, errorCode, $"存储过程ps_getemployee执行失败,返回值:{retVal}");
}

该方案的优势:

  • 语义清晰,一眼就能识别是存储过程执行失败的错误
  • 可以携带自定义的返回值、错误码等上下文数据
  • 符合.NET异常设计最佳实践,便于上层代码针对性捕获处理

2. 复用.NET内置通用异常

如果不想自定义异常,也可以选择合适的内置异常类型:

  • InvalidOperationException:适合表示操作处于无效状态时的错误,比如存储过程返回非零值意味着当前操作无法完成
  • ApplicationException:用于应用程序特定错误,但微软官方更推荐自定义异常而非直接使用它

示例:

if (retVal != 0)
{
    throw new InvalidOperationException($"存储过程ps_getemployee执行失败,返回值:{retVal}");
}

不推荐继续使用FaultException的原因

FaultException是专门为WCF服务设计的SOAP错误异常类型,如果你的项目不是WCF服务场景,使用它会导致语义不符,还会引入不必要的WCF依赖,增加代码复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:40:10