异常处理最佳实践
本文关键字:最佳 异常处理 | 更新日期: 2023-09-27 18:20:56
我想知道哪种方法是进行异常处理的最佳方法,因为在我的Try
语句中,我有很多验证,如果我在那里得到一些Exception
,我的Catch
语句可以告诉我发生了什么,但我怎么知道Exception
出现在哪个字段中呢?
样本代码
try
{
// If I get a Exception when converting to number,
// I will understand the error
// but how could I know where in my `Try` statement was the error ?
int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
Catch(Exception e)
{
this.LogInformation(e.Message);
}
将字符串转换为数字时,最佳做法是根本不使用Try-Catch
。因此,您应该使用类似int.TryParse
的TryParse
方法。
// note that here is also a possible error-source
string valorToken = xmlnode[i].ChildNodes.Item(2).InnerText.Trim();
int valor;
if(!int.TryParse(valorToken, out valor))
{
// log this
}
// else valor was parsed correctly
除此之外,如果要提供准确的错误消息,则必须使用多个try-catch
或处理不同的异常类型(最常见的Exception
类型必须是最后一个)。
如果不确定值,请不要使用Convert.ToInt32。改为使用Int32.TryParse:
int valor;
if (Int32.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
// Worked! valor contains value
}
else
{
// Not a valid Int32
}
此外,您不应该使用Exceptions来捕获验证错误。验证代码应该计算值是否正确,而不是在值不正确时失败。验证类应该期望接收有效和无效的数据作为输入。因为您期望无效的输入,所以当它无效时,不应该捕获异常。
想出一个测试来检查数据是否有效,并返回true或false。几乎所有的数字类型都有一个类似上面的TryParse方法。对于其他验证方法的自定义规则,提出一个规范,准确定义有效和无效输入,然后编写一个方法来实现该规范。
移动尝试。。catch内部循环。因此,您将知道究竟是哪个项目导致异常
foreach(var xmlNode in nodes)
{
try
{
//
int valor = Convert.ToInt32(xmlNode.ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
catch(Exception e)
{
LogInformation(e.Message); // current item is xmlNode
return;
}
}
如果要解析的字符串的值极有可能不可解析,因此这不是一种特殊情况。不应被视为例外。
在这种情况下,有TryParse
,它允许您确定该值对于解析无效:
int valor;
if(int.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
// "valor" is sucessfully parsed
}
else
{
// invalid parse - do something with that knowledge
}
除非创建了不同的异常(即不同的类),否则您需要使用不同的try-catch来处理此问题。
通常你可以做:
try
{
// If I get a Exception when converting to number,
// I will understand the error
// but how could I know where in my `Try` statement was the error ?
int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
Catch(IOException ioe) {
// Handle, log
}
Catch(ArgumentNullException ane) {
// Handle, log
}
Catch(Exception e)
{
// Handle, log and potentially rethrow
}
你也可以在你的尝试块中有单独的尝试捕获(我认为这是大多数人会做的事情)或嵌套的尝试捕获:
像
// First block
try {
// Convert here once
} catch (Exception ex) {
// Handle and log
}
// Second block
try {
// Convert here once
} catch (Exception ex) {
// Handle and log
}
不确定这是否有帮助。
try
{
}
catch (Exception ex)
{
var stackTrace = new StackTrace(ex, true);
var frame = stackTrace.GetFrame(0);
var line = frame.GetFileLineNumber();
var method = frame.GetMethod();
}