正在添加全局Try-Catch异常

本文关键字:Try-Catch 异常 全局 添加 | 更新日期: 2023-09-27 18:23:36

我用这种方式实现了全局Try-Catch机制。我添加了一个单独的类,称为HandleException.cs

public static class HandleException
{
    public static void GlobalTryCatch(Action action, object obj)
    {
        try
        {
            action.Invoke();
        }
        catch(SqlException ex)
        {
            obj.GetType().GetProperty("Success").SetValue(obj.GetType(), false);
            obj.GetType().GetProperty("FailureMessage").SetValue(obj.GetType(), ex);
        }
        catch(Exception ex)
        {
            obj.GetType().GetProperty("Success").SetValue(obj.GetType(), false);
            obj.GetType().GetProperty("FailureMessage").SetValue(obj.GetType(), ex);
        }
    }
}

这样称呼它。

public override Result<int> Update(UserProfile data)
    {
        var result = new Result<int> { Success = false };
        HandleException.GlobalTryCatch(() =>
                                           {
                                               SqlParameter[] sParam =
                                                   {
                                                       DbHelper.CreateParameter("@UserId", ParameterDirection.Input, SqlDbType.Int, data.UserId),
                                                       DbHelper.CreateParameter("@FirstName", ParameterDirection.Input, SqlDbType.VarChar,100, data.FirstName),
                                                       DbHelper.CreateParameter("@LastName", ParameterDirection.Input, SqlDbType.VarChar,100, data.LastName),
                                                       DbHelper.CreateParameter("@Gender", ParameterDirection.Input, SqlDbType.Char,1, data.Gender),
                                                       DbHelper.CreateParameter("@Dob", ParameterDirection.Input, SqlDbType.Date, data.DateOfBirth),
                                                       DbHelper.CreateParameter("@ImageUrl", ParameterDirection.Input, SqlDbType.VarChar, 150, data.ImageUrl),
                                                   };
                                               using(var sql = new DbHelper())
                                               {
                                                   sql.ExecuteSpReturnScalar("UserProfile_Update", sParam);
                                               }
                                               result.Success = true;
                                           }, result);
        return result;

}

我的问题是

  1. 这是实施全球试捕机制的标准做法吗?或者有其他标准方法可以实现吗
  2. 我在GlobalTryCatch方法中使用过这个。通过这种方式,我们是否可以通过传递泛型对象来为属性赋值?

    obj.GetType().GetProperty("成功").SetValue(obj.GetType(),false);

正在添加全局Try-Catch异常

这是实施全球尝试捕获机制的标准做法吗

不,不是。此外,上述"全球试抓机制"是一种不良做法。封装try-catch中的每个方法都假设,您肯定知道,在抛出任何异常之后该怎么办。在现实世界中,这是错误的。看看这个例子:

void AnyMethod()
{
    var result = // ...
    HandleException.GlobalTryCatch(() => { /* action 1 */}, result);
    // should we check result to continue?
    // if so, this is a typical error-code approach, which annihilates 
    // all preferences, provided by .NET exceptions;
    // if we shouldn't check it, what would be the behavior of our code,
    // if the state is broken after action 1? 
    HandleException.GlobalTryCatch(() => { /* action 2 */}, result);
    // the same questions
    HandleException.GlobalTryCatch(() => { /* action 3 */}, result);
}

不时使用类似的方法来记录异常(由于在.NET中实现时缺少开箱即用的方面):

void Execute(Action action)
{
    try
    {
        action();
    }
    catch (Exception e)
    {
        Logger.Log(e);
        throw;
    }
}
T Execute<T>(Func<T> func)
{
    try
    {
        return func();
    }
    catch (Exception e)
    {
        Logger.Log(e);
        throw;
    }
}

但是:
1) 它记录完整的异常信息(例如,您的代码缺少堆栈跟踪和内部异常)
2) 它重新抛出相同的异常(这允许使用.NET异常的所有好处)
3) 它只封装有限数量的顶级方法,而不是每个方法。

通过这种方式,我们是否可以通过传递泛型对象来为属性赋值?

你可以这样做:

interface IActionResult
{
    bool Success { get; set; }
    string FailureMessage { get; set; }
}
public static void GlobalTryCatch<T>(Action action, T obj)
    where T : IActionResult
{
    // ...
}

但这并不能取消你第一个问题的答案。

您可以使用http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx(或http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx用于WPF应用)。

一般来说,在这些事件中做一些有意义的事情并不是一个坏主意——记录异常(或将其发送给管理员)并向用户显示消息(比如"对不起,发生了错误,请联系您的管理员")。

但正如其他人所说,你应该在你的方法中处理借口,你可以用它们做一些有意义的事情,而不是在全球范围内。即使它在c#中不是强制性的,在注释中添加一个好主意,即您的方法在某些情况下可能会抛出某种异常。