正在添加全局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;
}
我的问题是
- 这是实施全球试捕机制的标准做法吗?或者有其他标准方法可以实现吗
我在
GlobalTryCatch
方法中使用过这个。通过这种方式,我们是否可以通过传递泛型对象来为属性赋值?obj.GetType().GetProperty("成功").SetValue(obj.GetType(),false);
这是实施全球尝试捕获机制的标准做法吗
不,不是。此外,上述"全球试抓机制"是一种不良做法。封装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#中不是强制性的,在注释中添加一个好主意,即您的方法在某些情况下可能会抛出某种异常。