예외 처리를위한 올바른 방법은 무엇입니까?


20

Joomla 핵심에서 여전히 다음과 같은 많은 호출을 찾습니다.

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

그러나 JError는 Platform 릴리스 12.1부터 더 이상 사용되지 않습니다. 표준 PHP 예외를 어떻게 사용해야합니까?


1
차이점은 JError에서 PHP Errors로 옮겨가는 것이 불행히도 한 번의 클릭 프로세스가 아니라는 것입니다. 따라서 예외가 발생한다고 확신하면 아래 답변과 같이 try / catch 문을 수행하십시오. JError를 얻는다고 확신한다면 위와 비슷한 코드를 작성해야합니다.)
George Wilson

답변:


17

@DmitryRekun이 말했듯이 좋은 토론이 여기 있습니다 . 이 모든 것에서 고려해야 할 핵심은 어떤 유형의 오류입니까?

두 가지 유형의 오류가 있습니다.

  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메시지와 코드라는 두 가지 매개 변수를 취하는 클래스입니다. 시나리오에 맞는 HTTP 응답 코드 를 사용하는 것이 좋습니다 .

오류가 복구 가능한 경우 최종 사용자에게 메시지를 표시하면서 요청한 페이지를 계속 표시하려고 할 수 있습니다. 이것은 일반적으로 응용 프로그램에 대한 메시지를 '인큐'해야 함을 의미합니다.

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

enqueueMessage오류 메시지와 메시지 유형의 두 매개 변수를 사용합니다. 자세한 내용은 여기 (아래)를 참조하십시오.


적어도 나에게 꽤 자주 발생하는 세 번째 상황도 있습니다. 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
}

수행중인 작업은 복구 할 수없는 오류를 "잡기"하고 시스템이 복구되어 요청 된 페이지를 계속 표시하도록하는 것입니다.


이 모든 것을 합하면 사건은 복구 할 수없는 오류가되어야합니다. (나중에 '거짓을 반환'했기 때문에 이것을 알고 있으므로 계속 계획하지 않고 기능을 포기할 것입니다.)

따라서 다음과 같이 다시 작성합니다.

// 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.
}

좋은 대답입니다! 그러나 $this->get('Errors')더 이상 사용되지 않으므로 의존하지 않습니다.
Dmitry Rekun

실패한 어설 션, 즉 내부 오류에 대한 의견이 있습니까? 어설 션이 실패하면 프로그램이 즉시 죽고 싶습니다. Joomla 고유의 ​​방법으로이 작업을 수행 할 수 있습니까? 경우 순간 나는 어설 핸들러를 등록 JDEBUG입니다 true.
Olle Härstedt

12

오류를 관리하는 방법은 다음과 같습니다.

보기 또는 컨트롤러

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');
}

따라서 내 모델 에서 404 코드를 얻는 경우 (예 :)

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

그런 다음 뷰 또는 컨트롤러에서 포착하여 Joomla가 처리하고 404 페이지를 표시하는 예외를 하나 더 발생시킵니다. 다른 어떤 경우에는 일반적인 오류 메시지를 사용자에게 보여줍니다.

또한 오류 처리에 대한이 흥미로운 토론을 읽으십시오 .


4

이와 같은 대부분의 코드 블록 enqueueMessage은 실제로 오류에 대한 조치를 취하지 않고 단순히 JError인쇄하는 데 사용되므로 간단히 대체 할 수 있습니다 .

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.