我发现需要多次复制并粘贴以下错误处理代码。在Catch语句中工作时我有什么选择?
这样做会在此过程中丢失有价值的信息吗? (示例:异常重新包装在另一个异常中,或丢失堆栈信息)
有人能说出myAbstractClass中的“throw”和下面的Select方法中的“throw”之间的区别吗?
以下是我要复制的示例代码
public class StackUserDataSource : AbstractEnhancedTableDataSource<StackUserDataServiceContext>
{
//.. stuff
public IEnumerable<StackUserDataModel> Select()
{
try
{
var results = from c in _ServiceContext.StackUserTable
select c;
var query = results.AsTableServiceQuery();
var queryResults = query.Execute();
return queryResults;
}
catch (StorageClientException e)
{
// Todo: consider sticking this in another central location
switch (e.ErrorCode)
{
case StorageErrorCode.AccessDenied:
break;
case StorageErrorCode.AccountNotFound:
break;
case StorageErrorCode.AuthenticationFailure:
break;
// ... Yadda yadda, handle some exceptions, not others.. this is a demo.
case StorageErrorCode.TransportError:
break;
default:
break;
}
throw;
}
}
更新:
我怀疑这是可能的,但我可以动态捕获和过滤外部库中的异常吗?概念就像这样
try
{
var results = from c in _ServiceContext.StackUserTable
select c;
var query = results.AsTableServiceQuery();
var queryResults = query.Execute();
return queryResults;
}
catch (MyExternalExceptionHelperDLL e)
{
// all exceptions referenced in MyExternalHelper are passed below
MyExternalExceptionHelper.ProcessException(e);
}
catch (exception)
{
}
因为MyExternalExceptionHelperDLL可能无法动态选择要监听的内容(即SQL,网络与文件,但不是身份验证)
try
{
var results = from c in _ServiceContext.StackUserTable
select c;
var query = results.AsTableServiceQuery();
var queryResults = query.Execute();
return queryResults;
}
catch (exception e)
{
MyExternalExceptionHelper.ProcessException(e);
// The problem is that I don't know how to catch exceptions thrown from that static method above,
// or how to override that exception handling...
}
但是使用上面的代码,我不清楚最终用户如何选择或覆盖我的事件处理方法。
答案 0 :(得分:1)
您只能在throw;
子句中直接调用catch
,而throw e;
可以在您拥有异常实例e
的任何位置调用throw;
。它们之间的区别在于throw e;
重新抛出异常,同时保持其原始堆栈跟踪不变,而throw e;
重置堆栈跟踪,以便看起来异常最初由switch
抛出 - 调试时可能会很烦人。因此,我建议您将StorageClientException
语句提取到以throw;
作为参数的单独方法,但将catch
直接保留在{{1}}子句中。
答案 1 :(得分:1)
你可以这样做。重要的是,throw
需要位于原始catch
块中,以便保留堆栈跟踪。
public IEnumerable<StackUserDataModel> Select()
{
try
{
...
}
catch (StorageClientException e)
{
// You could do this if there is no fancy processing to do
if (!IsCatchableException(e))
throw;
}
}
bool IsCatchableException(StorageClientException e)
{
... optionally do some fancy processing of the exception, e.g. logging....
switch (e.ErrorCode)
{
case StorageErrorCode.AccessDenied:
case StorageErrorCode.AccountNotFound:
....
return true;
}
}