Câu hỏi hay. Tôi nghĩ rằng đây là một vấn đề chung với E_RECOVERABLE_ERROR
PHP.
Những gì bạn có trong câu hỏi của bạn là xử lý ngoại lệ, không phải xử lý lỗi. Trình xử lý lỗi đang gây ra sự cố thực tế mà bạn thảo luận ở đây với các lỗi nghiêm trọng có thể bắt được ( E_RECOVERABLE_ERROR
) .
PHP 7 và HHVM đã giải quyết vấn đề này.
Tệ hơn với Magento vì trình xử lý lỗi không xử lý được điều này vì lớp lỗi 5.2.
Một loại xử lý lỗi hữu ích hơn sẽ xử lý lớp lỗi này và biến các lỗi này thành ErrorException s. Ví dụ (không phải bởi tôi, từ đây ):
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
Vì vậy, trong ánh sáng của Magento, trình xử lý lỗi mặc định là hàm toàn cục mageCoreErrorHandler
trong app/code/core/Mage/Core/functions.php
. Nó lấy của đăng ký thông qua Mage::app()
bởi các init()
phương pháp của Mage_Core_Model_App ( app/code/core/Mage/Core/Model/App.php
) (thông qua bảo vệ _initEnvironment()
phương pháp).
Một trình quan sátcontroller_front_init_before
đăng ký trình xử lý lỗi PHP của riêng bạn lên trên sẽ đủ sau đó (các trình xử lý lỗi trong PHP có thể xếp chồng lên nhau):
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
Các lỗi nghiêm trọng có thể bắt được sau đó được chuyển thành ngoại lệ và bạn có thể xử lý chúng trong mã mở rộng của riêng bạn hoặc chúng không bị phát hiện và sẽ được nhìn thấy trong nhật ký ngoại lệ (thay vì cửa hàng của bạn chạy gaga trên các loại sai như hành vi hiện tại là các chương trình chết đừng nói dối ). Trong PHP 7, ngoại lệ để tìm kiếm không phải là ErrorException mà là TypeException (là BaseException ) cho các lỗi nghiêm trọng hiện có thể bắt được .
Tất cả các lỗi khác được chuyển cho bộ xử lý lỗi của Magento.
Lưu ý: Tôi chưa thử điều này, đây là một bài viết nhưng tôi biết vấn đề bạn đang hỏi và phân tích xử lý lỗi đã được thực hiện đối với 1.5.1.0 và được xác minh theo 1.9.1.0 thông qua phân tích mã. Các xử lý lỗi xếp chồng nên làm việc. Tôi nối thêm một mã ví dụ mở rộng cho thấy hầu hết các phần làm việc.
Tôi chưa đóng gói cái này như một phần mở rộng magento nhưng nó nên được chuyển thẳng với modman. Tôi sẽ đặt nó trên github.
Phụ lục: Trình xử lý lỗi
Ví dụ mã sau đây ( bản demo trực tuyến ) cho thấy việc sắp xếp các trình xử lý lỗi và ngoại lệ ném vào lỗi nghiêm trọng có thể bắt được :
<?php
/**
* error handler demonstration
*
* stackable error handle with previous call and catchable error exceptions
*
* @author hakre <http://hakre.wordpress.com>
* @link /magento//a/64972/4115
*/
set_error_handler(function() {
$args = func_get_args();
var_dump("me is the previous error handler", $args);
});
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
$test = function(callable $test) {};
$a = $undefined; // provoke little warning
$test(new stdClass); // provoke catchable fatal error
Chương trình đầu ra
string(32) "me is the previous error handler"
array(4) {
[0]=>
int(8)
[1]=>
string(29) "Undefined variable: undefined"
[2]=>
string(45) "/tmp/execpad-0eca072b619d/source-0eca072b619d"
[3]=>
int(28)
}
Fatal error: Uncaught exception 'ErrorException' with message 'Argument 1 passed to {closure}() must be callable, object given, called in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 30 and defined' in /tmp/execpad-0eca072b619d/source-0eca072b619d:26
Stack trace:
#0 /tmp/execpad-0eca072b619d/source-0eca072b619d(26): {closure}(4096, 'Argument 1 pass...', '/tmp/execpad-0e...', 26, Array)
#1 /tmp/execpad-0eca072b619d/source-0eca072b619d(30): {closure}(Object(stdClass))
#2 {main}
thrown in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 26