埃菲尔(Eiffel)中的错误处理示例 [英] Examples of error handling in Eiffel

查看:150
本文介绍了埃菲尔(Eiffel)中的错误处理示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Eiffel中找不到错误处理的任何实质性例子.我只发现了一些琐碎的示例,或者它们完全忽略了错误,或者将错误处理留给了读者.我很想知道在没有异常的情况下错误如何在调用堆栈中传播.例如,我想知道发送网络请求的应用程序如何将已在呼叫链中检测到的网络问题通知用户.这样的事情.

I can't find any substantial example of error handling in Eiffel. I have only found examples that either are trivial, or they completely ignore errors, or they leave error handling to the reader. I am interested in knowing how errors can travel through the call stack in absence of exceptions. For example, I would like to know how an application that sends a network request would inform the user of a network problem that has been detected down the call chain. Something like that.

-

我确实知道埃菲尔(Eiffel)中错误处理的基本知识(状态和异常).但是,我找不到任何有关应用程序如何通过状态处理错误的大量示例.故障状态如何链接?

I do know the basics of error handling in Eiffel (statuses and exceptions). However, I can't find any substantial example on how applications handle errors via statuses. How are failure statuses chained?

推荐答案

Eiffel提倡使用对象状态而不是异常.在这种情况下,客户可能会弄​​清楚他们在发生错误时的期望并适当地处理它.例如,

Eiffel advocates use of an object state instead of exceptions. In that case clients may figure out what they expect in case of an error and handle it properly. For example,

has_error: BOOLEAN
        -- Has operation terminated with an error?

error_code: INTEGER
        -- Last error code or `no_error'.

is_closed: BOOLEAN
        -- Is connection closed?

response: detachable RESPONCE
        -- Last response if `not has_error'.

send_request (data: REQUEST)
    require
        is_open: not is_closed
    do
        ...
    ensure
        is_closed: is_closed implies (has_error and not connection.is_open)
        is_successful: not has_error implies attached response
    end

然后,客户可以推断出供应商对象的状态,并以可预测的方式继续使用它:

The client can then reason about the state of the supplier object and continue using it in a predictable way:

interface.send_request (...)
if interface.is_closed then
    ... -- The connection is unusable and should be reestablished.
elseif interface.has_error then
    ... -- Inspect `interface.error_code', possibly trying to resend the request.
else
    ... -- Use `interface.response' to continue processing.
end

在存在异常的情况下,除非从某些文档中得出,否则无法推断在什么情况下应采取的措施.此外,它还会阻止使用自动工具来轻松检查response在上面的代码中是否完全有效.

In presence of exceptions one cannot deduce what should be done in what case except from some documentation. Also, it prevents from using automatic tools that can easily check that the use of response is perfectly valid in the code above.

如果在堆栈的深处发生错误,则rescue/retry可以使用异常机制.但是,它可能会在底层网络组件和用户界面之间引入紧密耦合,这与网络故障的详细信息无关.在最简单的情况下,网络类将使用适当的消息来调用{EXCEPTIONS}.raise.更具体的方法是创建类型为EXCEPTION(或后代)的对象,通过在其上调用set_description设置相应的消息,并通过调用raise引发异常.可能会处理异常的用户代码如下.

If an error happens deep down the stack, an exception mechanism can be used with rescue/retry. However it may introduce close coupling between low-level network component and user interface that has nothing to do with details of network failure. In the simplest case, the network class will call {EXCEPTIONS}.raise with an appropriate message. A more specific approach would be to create an object of type EXCEPTION (or a descendant), to set the corresponding message by calling set_description on it, and to raise an exception by calling raise. The user code that will handle the exception may look like.

local
    is_retried: BOOLEAN
    e: EXCEPTIONS
do
    if is_retried then
            -- There was an exception, handle it.
        create e
        if e.developer_exception_name ~ "This error" then
            ... -- Do something.
        elseif e.developer_exception_name ~ "That error" then
            ... -- Do something else.
        else
            ... -- Report yet another error.
        end
    else
        ... -- Some code that may fail with an exception.
    end
rescue
    if not is_retried then
        is_retried := True
        retry
    end
end

编辑

处理嵌套错误的特定方法取决于应用程序设计,并且似乎与语言无关.可能的替代方法是:

A specific way to handle nested errors depends on the application design and seems to be irrelevant to the language. Possible alternatives are:

  1. (如果使用异常机制,则不建议使用..)在捕获(较低级别)异常并对其进行处理以恢复类不变性之后,将引发新的异常,而不会取消该异常.前一个.然后,查询({EXCEPTION}.cause)可以(递归)用于访问嵌套的异常对象.

  1. (If exception mechanism is used, not recommended.) After catching a (lower-level) exception and handling it to restore the class invariant, a new exception is raised without cancelling the previous one. Then a query {EXCEPTION}.cause can be (recursively) used to access nested exception objects.

可以使用与上一个类似的机制.但是,除了创建新对象外,类还可以将对详细信息的请求委派给较低级别​​的类.例如,

A mechanism similar to the previous one can be used. However instead of creating new objects, a class can delegate a request for details to a lower-level class. For example,

class A feature
    has_error: BOOLEAN
        do
            Result := nested.has_error
        end
    error: STRING
        do
            Result := "Cannot complete operation X. Reason: " + nested.error
        end
feature {NONE}
    nested: B
end

class B feature
    has_error: BOOLEAN
        do
            Result := nested.has_error
        end
     error: STRING
        do
            Result := "Cannot complete operation Y. Reason: " + nested.error
        end
feature {NONE}
   nested: C
end

  • 可以使用记录工具.它们可以区分错误严重性,指定来源等.

  • Logging facilities can be used. They can differentiate error severity, specify sources, etc.

    class A feature
        do_something
            do
                nested.whatever
                if nested.has_error then
                    log.error ("Cannot complete operation X.")
                end
            end
        has_error: BOOLEAN do Result := nested.has_error end
    feature {NONE}
        nested: B
    end
    
    class B feature
        whatever
            do
                nested.try_something
                if nested.has_error then
                    -- An error has been reported by "nested".
                elseif something_else_goes_wrong then
                    has_inner_error := True
                    log.error ("Something goes wrong.")
               elseif has_minor_issues then
                     log.warning ("Be careful.")
                end
            end
        has_error: BOOLEAN do Result := nested.has_error or has_inner_error end
        has_inner_error: BOOLEAN
                -- Some error that is not one of the errors reported by `nested'.
    feature {NONE}
       nested: C
    end
    

  • 这篇关于埃菲尔(Eiffel)中的错误处理示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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