2013-07-04 118 views
4

我想知道哪个是最好的异常处理方式,因为在我的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); 
} 
+0

对所有'Convert'抛出异常 –

+3

,如果您不是100%确定它们是有效的,则应该使用'TryParse'。例如。对于Int32:http://msdn.microsoft.com/en-us/library/f02979c7.aspx – Bolu

回答

3

最好的做法是不使用Try-Catch在所有当你将字符串转换为数字。因此,您应该使用TryParse方法,如int.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类型必须是最后一个)。

+0

但这只是一个例子,我有很多验证,不仅仅是'Convert.toInt32'。我只想让我的代码停在我的Catch语句中。 –

0

除非是那些获得创建了不同的异常(即不同类别),那么你就需要用不同的尝试捕获来处理这个问题。

通常你可以这样做:

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 
} 

您也可以有单独的试捕捞量(这是什么样的大多数人会做,我认为),或在你的try块嵌套尝试捕获:

// First block 
try { 
    // Convert here once 
} catch (Exception ex) { 
// Handle and log 
} 

// Second block 
try { 
    // Convert here once 
} catch (Exception ex) { 
// Handle and log 
} 

不知道这是否有帮助。

+0

您的标题提到了Exceptions Best Practices。如果它只是数字解析,那么我会去看看Tobsey的答案 – Yannis

1

Move try..catch inside loop。这样,你就会知道哪些项目正是造成异常

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; 
    } 
} 
0
try 
{ 
} 
catch (Exception ex) 
{ 
    var stackTrace = new StackTrace(ex, true); 

    var frame = stackTrace.GetFrame(0); 

    var line = frame.GetFileLineNumber(); 

    var method = frame.GetMethod(); 
} 
3

如果您不确定的价值,不要使用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 
} 

此外,您不应该使用异常来捕获验证错误。您的验证代码应该计算该值是否正确,而不是在不正确时失败。验证类应该期望接收有效和无效的数据作为输入。因为你期望输入无效,所以当它无效时你不应该捕获异常。

提出一个测试,检查数据是否有效并返回true或false。几乎所有的数字类型都有上面的TryParse方法。对于其他验证方法的自定义规则,提出了一个规范,该规范准确定义了有效和无效输入,然后编写实现该规范的方法。

1

如果你想要分析的值甚至是最不可能分析的,那么它就不是一个例外的情况。不应被视为例外。

在这种情况下,有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 
} 
+0

但这只是一个例子,我有很多验证,不仅仅是'Convert.toInt32'。我只想让我的代码停在我的Catch语句中。 –

+0

@Lucas_Santos - 我的回答也只是一个例子。你应该做一些你认为可能会失败的事情。 – Jamiec

+0

你不需要用'int valor = 0'赋值,用'int valor'声明就足够了! –