我的网页上有以下代码:
btnTest_Click(object sender, EventArgs e)
{
...
bool ret=myFunc(...);
if (ret)
{...}
else
{
lblStatus.Text="Some Text";
lblStatus.Visible=true;
}
}
private bool myFunc(...)
{
bool ret=false;
try
{
...
ret=true;
}
catch (Exception ex)
{
lblStatus.Text="Other Text";
lblStatus.Visible=true;
}
return ret;
}
如果myFunc中发生异常,则lblStatus始终显示“Some Text”而不是“Other Text”。这意味着myFunc中的catch块并不意味着什么。我想知道如何修复此代码以更好地处理异常?
更新:也许我的例子不是很好。但我的主要目的是询问调用和被调用函数之间异常处理的最佳实践。
答案 0 :(得分:4)
为什么被调用的函数在异常时设置标签文本,调用者在成功时设置它?
这是一个混合的比喻。让一方负责UI(关注点分离),而另一方负责工作。如果您希望被调用的函数具有容错能力,请尝试以下方法:
private bool myFunc(...)
{
bool ret ;
try
{
...
ret=true;
}
catch
{
ret = false ;
}
return ret;
}
然后你的来电者可以这样做:
bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;
if ( success )
{
// do something useful
}
答案 1 :(得分:1)
它显示“Some Text”,因为当myFunc
中发生异常时,它返回false。然后,您进入else
方法的btnTest_Click
块,再次将lblStatus.Text
设置为“Some Text”。
因此,基本上,您将标签的文本设置为“其他文本”,然后设置为“某些文本”。
答案 2 :(得分:1)
你的catch
条款做得很多。它捕获每个异常并“忘记它”将其抑制到调用堆栈的其余部分。这可以很好,但我会尝试解释你的选择:
您通常有3个选项:
我使用了所有这些。
选项1
您可以实现您的功能,如果发生异常,则表示发生了一些故障,您只希望应用程序失败(至少达到某个级别)
选项2
发生了一些异常,你需要做两个(甚至两个)中的一个
选项3 预计会有例外,您知道如何对其做出完全反应。例如,在您的情况下,我倾向于认为您不关心异常的类型,但希望通过将某些控件设置为给定文本来“良好默认”。
<强>结论强>
没有银子弹。为每个方案使用最佳选项。
然而,捕捉和“抑制”catch(Exception ex)
是罕见的,如果经常看到它通常意味着糟糕的编程。
答案 3 :(得分:0)
异常处理很好。代码的问题在于,如果返回值为"Some Text"
,则将false
字符串放在标签中,即存在异常时,因此它将替换来自{{{}的消息。 1}}阻止。
切换案例:
catch
答案 4 :(得分:0)
这是一个复杂的问题所以我会尝试将其分解
null
(这将引发异常)。例外可能很慢(特别是如果抛出很多)myFunc
访问远程服务器并返回true或false状态,则您希望它处理自己的IO异常。它可能无法处理(或重新抛出)任何参数问题。这与第1点有关。功能责任处理连接过程,而不是提供正确的参数。如果其他人(或健忘的人)试图在以后使用该代码,则隐藏某些异常会导致问题。例如,在建立连接的myFunc
中,如果隐藏参数异常,您可能没有意识到已经传递了错误的参数答案 5 :(得分:0)
如果您想要了解在某个函数中遇到特定类型的错误,我建议继承Exception并创建自己的异常类。我在你的btnTest_Click()处理程序中放了一个try-catch块,然后我就会抓住你的自定义异常类。这样,您就不会失去检测myFunc()函数内发生的任何错误的机会。
答案 6 :(得分:0)
我通常会设置一个错误处理系统。这是一种简单的方法,但这可以包含在基类中。如果你需要,我可以告诉你。
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}