模式在本地处理预期的错误,反驳出意外的错误 [英] Pattern to handle expected errors locally, rethrow unexpected errors

查看:133
本文介绍了模式在本地处理预期的错误,反驳出意外的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时一定程度的代码会以预期的方式引发错误,最方便的是在本地处理它,而不是将其抛出到一个错误处理例程中,它会与其他相同类型的错误混淆。然而,你不希望吞咽意外的错误;你希望他们像往常一样抚养。

Sometimes a certain bit of code will raise an error in an expected way, and it's most convenient to handle it locally rather than throw it to an error handling routine where it will get mixed up with other errors of the same type. Yet you don't want unexpected errors to be swallowed; you want them to be raised as usual.

在下面的(稍微设计的)示例中, FindInArray 函数可以引发不同类型的错误。其中一个, ERR__ELEMENT_NOT_FOUND_IN_ARRAY ,或多或少的预期,所以我想在本地处理它。但是也可能会出现其他错误号,如果是这样,我希望它们被错误处理程序处理。

In the (slightly contrived) example below, the FindInArray function can raise different types of error. One of them, ERR__ELEMENT_NOT_FOUND_IN_ARRAY, is more or less expected and so I want to handle it locally. But other error numbers may also occur, and if so I want them to be dealt with by the error handling routine.

我发现,如果我在本地处理一些预期的错误号码,我不能轻易地推翻意外的错误号码在其他地方处理。

I find that if I deal with some expected error numbers locally, I can't easily "rethrow" unexpected error numbers to be dealt with elsewhere.

如何将我想要处理的预期错误与本地处理的错误处理例程(或其他地方)中的意外错误进行隔离?

How do I segregate the expected errors I want to deal with locally, from unexpected errors to be dealt with in error handling routine (or elsewhere)?

On Error GoTo ErrorHandler

'Some code...

'Here I want to trap a likely/expected error locally, because the same
'error may occur elsewhere in the procedure but require different handling.
On Error Resume Next
personIndex = FindInArray(personName, personArray)
If Err.Number = ERR__ELEMENT_NOT_FOUND_IN_ARRAY Then
    MsgBox "Name not found in person array. Using default person."
Else
    'What if it's a different kind of error?
    ' .e.g. ERR__ARRAY_CONTAINS_TWO_PERSONS_WITH_SAME_NAME
    'I want to rethrow it, but can't because On Error Resume Next swallows it.
End If
On Error GoTo ErrorHandler 'back to normal
'I can't rethrow it here either, because On Error Goto cleared the Err object.

'-----------------------
ErrorHandler:
Select Case Err.Number
Case ERR__ELEMENT_NOT_FOUND_IN_ARRAY
    'The error number doesn't give me enough info 
    'to know what to do with it here!
Case ERR__ARRAY_CONTAINS_TWO_PERSONS_WITH_SAME_NAME
    'Existing code to deal with this error
Case ...

我想我可以保存一些其他变量/对象中的错误号,源,描述等,并使用这些在 On Error GoTo ErrorHandler之后引发错误回到正常的(实际上我已经实现了这个只是为了看到),但这似乎是非常不方便和笨拙。

I guess I could "save" the error Number, Source, Description, etc. in some other variable / object, and use those to raise an error after On Error GoTo ErrorHandler 'back to normal, (and in fact I have implemented this just to see) but that seems terribly inconvenient and clumsy.

推荐答案

这个答案是我对手头问题的看法,也许从略有不同的角度来看。

This answer is my opinion on the problem at hand, perhaps viewed from a slightly different angle.

在考虑此代码块时:

On Error Resume Next
personIndex = FindInArray(personName, personArray)
If Err.Number = ERR__ELEMENT_NOT_FOUND_IN_ARRAY Then
    MsgBox "Name not found in person array. Using default person."
Else
End If

您提到标题中的预期错误 。

但事实是,如果您事先知道可能会发生错误,则不应该抛出任何错误。

它们是一种验证在我看来应该以条件语句的形式构建在函数中。

You mention: "expected errors" in the title.
But the thing is that no error should be thrown if you know in advance that it may occur.
They are a form of validation that should in my opinion be built in into the functions in the form of conditional statements.

前面提到的代码块在基本级别上将是这样的:

The before mentioned code block would be something like this on a basic level:

    If Not (in_array(vArray, "Jean-Francois")) Then
        MsgBox "Name not found in person array. Using default person."
    End If

在我看来,这是一个更清洁和可读的。

使用不属于基本代码的自定义函数,但是在幕后进行检查。可重复使用的函数可以包装在一个与静态类非常相似的方式中使用的模块中。

Which in my opinion is a lot cleaner and readable.
With a custom function that is not part of the base code, but that does your check behind the scenes. Reusable functions can be wrapped in a module that you use in a way that is very similar to a static class.

Public Function in_array(vArray As Variant, sItem As String) As Boolean

    Dim lCnt As Long

    in_array = False
    Do Until lCnt = UBound(vArray) + 1
        If StrComp(vArray(lCnt), sItem, CompareMethod.Text) = 0 Then
            in_array = True
            Exit Function
        End If
        lCnt = lCnt + 1
    Loop

End Function

更好的是使用 in_array()函数> findInArray()函数,并且在basesubub中只有一行代码,这将是:

Even better would be to use the in_array() function from within the findInArray() function and have only 1 line of code in the basesub, which would be:

personIndex = FindInArray(personName, personArray)

让后面的函数处理休息和截取异常你可以预见。

这只是一个例子,显然你编写的函数和返回值对你有用,你可以添加更多的扩展验证。

Let the functions in the back handle the rest and intercept exceptions that you can foresee.
This is only an example, obviously you write the functions and return values that are useful for you and you could probably add more extensive validation.

我的观点是这些返回值是作为应用程序/验证逻辑的一部分的返回消息,我不认为它们是技术错误 - 因此,我使用错误处理程序作为自定义创建的函数,看到任何好处,完全符合您的需求(我的意见)更清洁的结构。

My point is that these return values are return messages that are a part of the application / validation logic, I don't see them as technical errors - hence, I don't see any benefit in using an error handler for them as a custom created function exactly fits your needs in a (my opinion) much cleaner structure.

当您将函数调用中的三个参数传递给它时,我认为这是一个技术错误,而它只接受两个参数。错误处理程序通知您,之后开发人员可以通过允许例如决定使当前功能更具动态性。可选参数和修复错误。

I consider it a technical error when you pass for example three arguments into the function call while it only accepts two. The error handler notifies you, after which the developer may decide to make the current function more dynamic by allowing eg. optional parameters and fixing the bug.

这篇关于模式在本地处理预期的错误,反驳出意外的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆