web-dev-qa-db-ja.com

例外処理の正しい方法は何ですか?

Joomlaコアでは、次のような呼び出しがまだたくさん見つかります。

    // Check for errors.
    if (count($errors = $this->get('Errors')))
    {
        JError::raiseError(500, implode("\n", $errors));
        return false;
    }

ただし、JErrorはプラットフォームリリース12.1以降廃止されました。だから私は標準のPHP例外をどのように使うべきですか?.

20
Harald Leithner

@DmitryRekunが言ったように、良い議論は here です。このすべてで考慮すべき重要な点は、どのような種類のエラーがあるかです。

エラーには2つのタイプがあります。

  1. 回復可能
  2. 回復できません。

違いをまとめると、次のようになります。

Can I still show the page that was requested, even though this error occurred?
  • はい? -回復可能
  • 番号? -回復不能

これで、何を扱っているかがわかりました。あなたは何をするべきか?

エラーが回復できない場合は、エラーページにリダイレクトすることをお勧めします要求されたページに進むのではなく。これは次のように簡単です。

throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);

Exceptionは、メッセージとコードの2つのパラメーターを受け取るクラスです。 HTTP応答コード を使用することをお勧めします(シナリオに適している場合)。

エラーが回復可能な場合は、エンドユーザーに要求したページを表示したまま、エンドユーザーにメッセージを表示することをお勧めします。これは通常、アプリケーションのメッセージを「エンキュー」する必要があることを意味します。

JFactory::getApplication()->enqueueMessage($error, 'error');

enqueueMessageは、エラーメッセージとメッセージタイプの2つのパラメーターを取ります。詳細 ここ (下部)。


少なくとも私にとってかなり頻繁に発生する3番目の状況もあります。 Joomlaは、さまざまなエラー(データベースクエリエラーなど)に対して例外をスローします。これは、Joomlaがこのエラーを回復できないと考えていることを意味します。ただし、とにかく続行することができます。 (たとえば、拡張機能の更新時にテーブルを変更する場合は、ALTERクエリを実行するだけで済みます。テーブルが以前に変更されている場合は、例外がスローされます。)

その場合、例外をスローする可能性のあるコードをtry ... catchセクションでラップします。

try {
    // exception generating code
    throw new Exception('Normally you would have other code that calls a class that throws the exception', 500);
} catch (Exception $e) {
    $msg = $e->getMessage(); // Returns "Normally you would have other code...
    $code = $e->getCode(); // Returns '500';
    JFactory::getApplication()->enqueueMessage($msg, 'error'); // commonly to still display that error
}

あなたがやっていることは、回復不可能なエラーを「キャッチ」し、システムを強制的に回復させ、要求されたページを表示し続けることに注意してください。


これをすべて追加すると、ケースは回復不可能なエラーになります。 (後で 'falseを返す'ため、これを知っているので、続行する予定がなく、関数をあきらめている可能性があります。)

したがって、これを次のように書き換えます。

// Check for errors.
if (count($errors = $this->get('Errors')))
{
    throw new Exception(implode("\n", $errors), 500);
    return false; // you can remove this too, technically since the exception will take you out of this function.
}
18
David Fritsch

これがエラーの管理方法です。

ViewまたはController

try
{
    $this->item = $this->get('Item');
}
catch (Exception $e)
{
    if ($e->getCode() == 404)
    {
        // Not found
        throw new Exception($e->getMessage(), 404);
    }

    // Generic errors
    JFactory::getApplication()->enqueueMessage(JText::_('COM_MYCOMP_ERROR_OCCURRED'), 'error');
}

したがって、Model(たとえば)から404コードを取得した場合:

if (empty($data))
{
    throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);
}

次に、それをビューまたはコントローラーでキャッチし、Joomlaが処理して404ページを表示する例外をもう1つスローします。その他の場合は、一般的なエラーメッセージをユーザーに表示します。

また read エラー処理に関するこの興味深い議論。

12
Dmitry Rekun

このようなコードブロックのほとんどは、実際にはエラーに対応しておらず、単にenqueueMessageを使用して出力するため、JErrorに置き換えることができます。

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
4
Spunkie