异常处理的良好实践设计模式
本文关键字:设计模式 异常处理 | 更新日期: 2023-09-27 17:59:41
我在每个方法中都有异常处理代码,下面是底层方法的代码
throw new Exception("The error that happens");
有什么办法可以避免在每个方法中一遍又一遍地写这段代码吗?
我正在尝试写我自己的代码,而不使用任何日志框架
private void TopLevelMethod()
{
try
{
SomeMethod();
}
catch (Exception ex)
{
// Log/report exception/display to user etc.
}
}
private void SomeMethod()
{
TestPartA();
TestPartB();
TestPartC();
TestPartD();
}
private void TestPartA()
{
// Do some testing...
try
{
if (somethingBadHappens)
{
throw new Exception("The error that happens");
}
}
catch (Exception)
{
// Cleanup here. If no cleanup is possible,
// do not catch the exception here, i.e.,
// try...catch would not be necessary in this method.
// Re-throw the original exception.
throw;
}
}
private void TestPartB()
{
// No need for try...catch because we can't do any cleanup for this method.
if (somethingshappens)
{
throw new Exception("The error that happens");
}
}
只有当您想对错误做一些有意义的事情时才会捕获错误,例如:
- 用框架异常包装异常(例如
SqlException
.ADO.NET从不向您传递套接字级错误。它会向您传递有意义的SQL错误代码) - 清理
- 实际响应(例如重试或插入默认值)
日志记录几乎从来都不合适。顶级处理程序应该进行日志记录。当然,并不是路径中的每个方法都应该进行日志记录。日志和代码真是一团糟。不要那样做。
不要轻信错误信息,让错误冒出来。这样就没有理由在任何地方插入错误的本地日志记录代码。
如果您喜欢使用类似函数式编程的代码风格,一种方法是使用回调错误回调。示例:
private void SomeMethod()
{
// do something
}
public bool Execute(Action act, Action<Exception> onErrorCallback)
{
var res = true;
try
{
act();
}
catch (Exception ex)
{
res = false;
onErrorCallback(ex);
}
return res;
}
并像这样使用Execute
:
var successfull = true;
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
if (!successfull)
; // show user or something else
涂鸦:请你举一个示例代码。谢谢。。。
您的代码重构:
private void TopLevelMethod()
{
List<string> errors=new List<string>() ;
if (!SomeMethod(errors)) { /* Log/report errors/display to user etc. */ }
}
private bool SomeMethod(List<string> errors)
{
return TestPartA(errors) && TestPartB(errors) && TestPartC(errors) && TestPartD(errors);
}
private bool TestPartA(List<string> errors)
{
bool result = true ;
try
{
// Do some testing...
if (somethingBadHappens) { result=false; errors.Add("The error that happens"); }
}
catch (Exception ex) { errors.Add("Error in TestPartA: "+Ex.Exception.Message.ToString()) ; }
return result ;
}
private bool TestPartB(List<string> errors)
{
bool result = true ;
// Do some testing...
if (somethingBadHappens) { result = false ; errors.Add("The error that happens"); }
return result ;
}