Как обрабатывать уведомления php, предупреждения и ошибки в API REST?

В REST API ответ 200 показывает успешную операцию. PHP по умолчанию выводит сообщение об ошибке непосредственно в тело ответа, не меняя код ответа. В SPA текст ответа не виден пользователю напрямую. Поэтому, когда приложение не работает должным образом, я должен проверить тело ответа через FireBug, чтобы проверить возможные исключения PHP (которые приводят к неверному ответу json).
Есть ли способ отправить определенный код HTTP на все ошибки PHP?

Есть ли способ изменить код ответа HTTP в зависимости от наличия ошибок PHP? Или, возможно, получить текст ошибки и отправить его в формате JSON без проблем. (в стадии разработки)

Обновление: ловля исключений (try / catch / final) — это не то, что я ищу.

11

Решение

Допустим, например, что вас беспокоят только фатальные ошибки времени выполнения, фатальные ошибки времени компиляции и предупреждения во время выполнения. Установите для сообщения об ошибках желаемый уровень с Отчет об ошибках() функция.

error_reporting( E_ERROR | E_COMPILE_ERROR | E_WARNING );

Поскольку определяемый пользователем обработчик ошибок (ниже) не может обрабатывать фатальные ошибки, сообщения о фатальных ошибках все равно будут отображаться. Чтобы избежать этого использования ini_set () функционировать и установить display_errors в ноль.

ini_set( 'display_errors', 0 );

Теперь создайте собственный обработчик ошибок с set_error_handler () полностью обойти PHP обработчик ошибок для указанных типов ошибок (не относится к фатальным ошибкам).

/* The following error types cannot be handled with a user defined function:
*  E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING
* The standard PHP error handler is completely bypassed for the error types specified
*  unless the callback function returns FALSE.
*/
function exception_error_handler( $severity, $message, $file, $line )
{
if ( !( error_reporting() & $severity ) ) {
// This error code is not included in error_reporting
return;
}

// code for handling errors
}
set_error_handler( "exception_error_handler" );

Фатальные ошибки могут быть обработаны при выключении с помощью register_shutdown_function (). Обработчик выключения выполняется после завершения сценария или прекращается (это также относится к ошибкам). Нам нужно получить информацию о последней произошедшей ошибке ( error_get_last () ) далее следует проверить, является ли это типом ошибки, которую мы отслеживаем (что она здесь на самом деле не нужна, поскольку ошибки, не указанные в error_reporting не сработает, но это может быть полезно для фильтрации ошибок) и, наконец, вызов обработчика исключений.

function fatal_error_shutdown()
{
$last_error = error_get_last();
if ( error_reporting() & $last_error['type'] )
call_user_func_array( 'exception_error_handler', $last_error );
}
register_shutdown_function( 'fatal_error_shutdown' );

Теперь вы можете использовать пользовательский обработчик исключений, чтобы перехватывать необработанные исключения (в том числе фатальные) и форсировать код ответа (с помощью Заголовок () функция).

10

Другие решения

Конечно, вы можете изменить статус HTTP в PHP:

<?php
header("HTTP/1.1 502 Bad Gateway");
?>

Вы можете изменить сообщение и код, но вы должны быть осторожны с стандартные коды

10

set_error_handler Функция — это то, что я пропустил. Я придумал следующий код. Любой лучший ответ приветствуется.

function jsonErrorHandler()
{
if (error_reporting()) {

http_response_code(500);
header('Content-Type: application/json; charset=utf-8');
$response = array_combine(['errno', 'errstr', 'errfile', 'errline', 'errcontext'], func_get_args());
die(json_encode($response));

}
}

set_error_handler('jsonErrorHandler');
6

Используйте рамки или библиотека обработчика ошибок.

В зависимости от того, какую платформу вы выберете, вы можете настроить, как этот обработчик ошибок представляет ошибки. Обработчик ошибок, с которым я связан, по-видимому, поддерживает сериализацию ошибок в JSON по умолчанию, вам следует ознакомиться с его документацией.

С рамкой, вот пример для Laravel 4:

App::error(function(Exception $exception, $code) {
Log::error($exception);
return Response::json(["code" => $code, "message" => $exception->getMessage()], $code);
});

Обратите внимание, что если вы полагаетесь на глобальный обработчик ошибок, обычно есть проблема в другом месте — вы не должны полагаться на него для обработки своих ошибок; вместо этого используйте try / catch, где это необходимо.

5

Хотя на некоторую часть вашего вопроса ответили здесь Возврат http кодов состояния с API отдыха

Я бы посоветовал не отправлять другой http-код для множества предупреждений, ошибок и уведомлений. Должна сработать внутренняя ошибка сервера 500 (http code 500), и вам не нужно раскрывать подробности ошибки своим пользователям API. Конечно, вы можете регистрировать все ошибки / уведомления / предупреждения для отладки и исправления вашего приложения.

Кроме того, от вашей логики приложения зависит и то, какие ошибки нужно сообщать пользователям, такие как проверка данных, бизнес-логика и т. Д.

3

Ты можешь использовать register_shutdown_function() с error_get_last() PHP функции для выявления любых ошибок и возврата правильного ответа. Есть рабочий пример что с помощью в RockWall REST двигатель

3

Код состояния HTTP отправляется в заголовках ответа HTTP, что означает, что вы можете изменить его, когда захотите, если PHP не отправил ни одного байта клиенту. Если это уже произошло, вы, скорее всего, получите Невозможно изменить информацию заголовка — заголовки уже отправлены ошибка.

PHP имеет несколько функций для изменения кода состояния, я бы рекомендовал http_response_code(), так как это проще в использовании: вам нужно только отправить код состояния HTTP, и он напишет полный заголовок для вас.

Чтобы ловить ошибки, я бы предложил установить обработчик ошибок.

function log_error($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array())
{
// Save the error to the error log.
// You may want to add more information than $errstr in the log, so feel free to change this line.
error_log($errstr);

// If headers haven't been sent, you can set a new one.
if (!headers_sent())
{
// 500 is the most generic error when the error comes from your application.
http_response_code(500);

// Checking if you're in debug mode allows you to show you errors while developping, and hiding them for users.
// Change this line by your own checks.
if (IS_DEBUG)
{
// Send the correct Content-Type header.
header('Content-Type: application/json; charset=utf-8');

// Sending information about the error.
echo json_encode(array(
'error' => $errstr // Once again, you may want to add more information.
));

// Exiting since we do not want the script to continue.
exit;
}
else
{
// Do whatever you want here, it will be shown to your users if you're not in debug mode.
// But do not forget to exit.
exit;
}
}
}

// Setting your function as an error handler.
set_error_handler('error_handler');

Поскольку исключения не обрабатываются обработчиком ошибок в PHP, я бы также предложил установить обработчик исключений.

Каждая ошибка PHP, обнаруженная вашим приложением во время выполнения (исключая, например, ошибки синтаксического анализа), теперь будет отправлять 500 Internal Server Error ответ, с подробной информацией об ошибке, если вы хотите.

3

В Yii Framework обработка таких проблем очень эффективна.

Они использовали PHP set_exception_handler ( ‘exceptionHandlerFunction’) а также set_error_handler ( ‘errorHandlerFunction’) функция для обработки всех типов исключений и ошибок (предупреждения, уведомления) соответственно.

О фатальной ошибке, register_shutdown_function ( ‘fatalHandlerFunction’)

Теперь, для демонстрации, Yii работает очень эффективно.

В функции обработчика ошибок / исключений / неустранимых изменений конфигурация позволяет либо выдавать ошибку на клиентскую сторону, либо отображать хорошо отформатированную ошибку.

Если хотите отображать хорошо отформатированный, Yii передает маршрут к действию Error SystemController.

Вы также можете пройти через Как Yii обрабатывает ошибки.

Надеюсь, поможет !!

1
По вопросам рекламы [email protected]