3

Eiffel でのエラー処理の実質的な例は見つかりません。些細な例、またはエラーを完全に無視する例、またはエラー処理を読者に任せている例しか見つかりませんでした。例外がない場合に、エラーがコール スタックをどのように移動するかを知りたいです。たとえば、ネットワーク要求を送信するアプリケーションが、コール チェーンで検出されたネットワークの問題をユーザーに通知する方法を知りたいです。そんな感じ。

--

編集: Eiffel でのエラー処理の基本 (ステータスと例外) は知っています。ただし、アプリケーションがステータスを介してエラーを処理する方法に関する実質的な例は見つかりません。障害ステータスはどのように連鎖されていますか?

4

2 に答える 2

3

Eiffel は、例外の代わりにオブジェクトの状態を使用することを提唱しています。その場合、クライアントは、エラーが発生した場合に何を期待するかを理解し、適切に処理できます。例えば、

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

その後、クライアントはサプライヤ オブジェクトの状態について推論し、予測可能な方法でそれを使用し続けることができます。

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また、上記のコードで の使用が完全に有効であることを簡単に確認できる自動ツールを使用できなくなります。

rescueスタックの奥深くでエラーが発生した場合は、 /で例外メカニズムを使用できますretry。ただし、ネットワーク障害の詳細とは関係のない、低レベルのネットワーク コンポーネントとユーザー インターフェイスとの間の密接な結合が生じる可能性があります。最も単純なケースでは、ネットワーク クラスは{EXCEPTIONS}.raise適切なメッセージで呼び出します。より具体的なアプローチは、型EXCEPTION(または子孫) のオブジェクトを作成し、それを呼び出して対応するメッセージを設定し、呼び出しset_descriptionて例外を発生させることraiseです。例外を処理するユーザー コードは次のようになります。

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

編集

ネストされたエラーを処理する特定の方法は、アプリケーションの設計に依存し、言語とは無関係のようです。可能な代替手段は次のとおりです。

  1. (例外メカニズムが使用されている場合は、お勧めしません。 ) (下位レベルの) 例外をキャッチし、それを処理してクラスの不変条件を復元した後、前の例外をキャンセルせずに新しい例外が発生します。その後、クエリ{EXCEPTION}.causeを (再帰的に) 使用して、ネストされた例外オブジェクトにアクセスできます。

  2. 前のものと同様のメカニズムを使用できます。ただし、新しいオブジェクトを作成する代わりに、クラスは詳細の要求を下位レベルのクラスに委任できます。例えば、

    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
    
  3. ロギング機能を使用できます。エラーの重大度を区別したり、ソースを指定したりできます。

    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
    
于 2014-11-16T13:28:08.120 に答える