Fatal error happen when your program process over the php memory limit, or longer process time. It will cause your program to abort or stop the existing process. Without proper handle this issue, the page might look unprofessional.
Here is the tutorial:
Step 1. Prepare file (lib/error.handler.php) with the following code:
function fatalErrorHandler()
{
// Where yii_log function located
require_once( __DIR__.DIRECTORY_SEPARATOR.'backend.lib.php');
//to get last error message
$error = error_get_last();
// To track fatal run-time errors
If ($error['type'] == E_ERROR){
// to log error note and send email alert.
yii_log($error, 'error');
// temporary key for jquery to validate
echo '<div style="display:none" id="fatal-error">true</div>';
}
}
register_shutdown_function('fatalErrorHandler');
Step 2. Include the following code in (config/web.php and config/console.php)
include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../lib/error.handler.php');
Step 3. Prepare file (lib/backend.lib.php) with the following code:
function yii_log($message, $level, $exit = FALSE) {
$message = is_array($message) ? $message['message'] : $message;
$message = date('Y-m-d H:i:s', time()). ' ' . substr((string)microtime(), 1, 8) . ' - ' . $message;
switch (strtolower($level)) {
case 'error':
Yii::error($message);
break;
case 'warning':
Yii::warning($message);
break;
case 'info':
Yii::info($message);
break;
case 'trace':
default:
Yii::trace($message);
break;
}
// Yii::log($message, $level);
Yii::getLogger()->flush();
// also alert via email
send_email_alert($message);
if($exit) {
exit();
}
}
function send_email_alert($message) {
$from = get_no_reply_email();
$sendTo = get_alert_email();
$app_name = Yii::$app->name;
$headers="From: {$from}\r\nReply-To: {$from}";
mail($sendTo, $app_name . ' Alert', $message, $headers);
}
Step 4. Prepare Ajax file (check_error.js) checking
$(document).ready(function() {
if ($("#fatal-error").length) {
//$("upload-csv-form").before('
File: '+decodeURIComponent(getCookie('csvfile')).match(/"(.+)"/)[1]+' import was failed!
');
var filename = decodeURIComponent(getCookie('csvfile')).match(/"(.+)"/)[1];
var postData = { csvfile: filename};
if (typeof yii.getCsrfToken != 'undefined' && yii.getCsrfToken() != '' )
{
postData[yii.getCsrfParam()] = yii.getCsrfToken();
}
$.ajax({
url: '/member/updatestatus',
data: postData,
type: 'POST',
dataType: 'jason',
success: function(){
}
});
$("pre").replaceWith('Importing of '+filename+' did not complete successfully because of a server side error (no memory, performance issues or connection issues).
');
}
});
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
}
Step 5. Register js file in view file
$this->registerJsFile($this->getAssetManager()->getPublishedUrl('@app/themes/dashboard').'/js/check_error.js', ['position' => $this::POS_END]);