Skip to content

Instantly share code, notes, and snippets.

@rmarscher
Created August 24, 2012 03:58
Show Gist options
  • Save rmarscher/3445265 to your computer and use it in GitHub Desktop.
Save rmarscher/3445265 to your computer and use it in GitHub Desktop.
li3 airbrake in errors bootstrap
<?php
use lithium\action\Response;
use lithium\core\Environment;
use lithium\core\ErrorHandler;
use lithium\core\Libraries;
use lithium\console\Response as ConsoleResponse;
use lithium\net\http\Media;
use lithium\analysis\Logger;
use lithium\net\http\Service;
use lithium\action\Request;
use lithium\console\Request as ConsoleRequest;
// @todo pull this in from li3_airbrake config
$airbrake = array(
'key' => '',
'secure' => false
);
// @todo put into a class and make filterable
$notifier = function($info, $params = null) use ($airbrake) {
$info['hostname'] = `hostname`;
$exception = $info['exception'];
$code = $exception->getCode();
$msg = '';
if (isset($params['request'])) {
$request = $params['request'];
if ($request instanceof ConsoleRequest) {
$command = "li3 " . implode(' ', $params['request']->argv);
} else {
$command = $request->to('url');
}
$msg .= $command . " - ";
}
$msg .= $exception->getMessage() .
' in ' . $exception->getFile() .
' on line ' . $exception->getLine() . '. ' .
$info['hostname'];
$return = compact('info', 'params', 'msg');
try {
Logger::write('error', $msg);
Logger::write('debug', $msg);
if (empty($airbrake['key'])) {
return $return;
}
$api = new Service(array(
'host' => 'airbrake.io',
'scheme' => $airbrake['secure'] ? 'https' : 'http'
));
$notice = new SimpleXmlElement('<notice></notice>');
$notice->addAttribute('version', '2.2');
$notice->{'api-key'} = $airbrake['key'];
$notifier = $notice->addChild('notifier');
$notifier->name = 'li3_airbrake';
$notifier->version = '0.1';
$notifier->url = 'http://github.com/Affinitive/li3_airbrake';
$error = $notice->addChild('error');
$error->class = get_class($exception);
$error->message = $exception->getMessage();
$backtrace = $error->addChild('backtrace');
$bt = $exception->getTrace();
if ($exception instanceof ErrorException) {
array_shift($bt);
}
foreach ($bt as $trace) {
$line = $backtrace->addChild('line');
$line->addAttribute('file', isset($trace['file']) ? $trace['file'] : "unknown");
$line->addAttribute('number', isset($trace['line']) ? $trace['line'] : "0");
if (!empty($trace['function'])) {
$line->addAttribute('method', $trace['function']);
}
}
if (isset($params['request'])) {
$request = $notice->addChild('request');
$request->url = $command;
if (!empty($params['request']->params)) {
$ignoreParams = array('controller', 'command', 'action');
if (isset($params['request']->params['command'])) {
$request->component = $params['request']->params['command'];
}
if (isset($params['request']->params['controller'])) {
$request->component = $params['request']->params['controller'];
}
$request->action = $params['request']->params['action'];
$requestParams = $request->addChild('params');
foreach ($params['request']->params as $name => $param) {
if (in_array($name, $ignoreParams)) {
continue;
}
if (is_array($param) || is_object($param)) {
$param = json_encode($param);
}
$requestParams->addChild('var', htmlentities($param, ENT_QUOTES, 'UTF-8'))
->addAttribute('key', $name);
}
}
if (!empty($_SESSION)) {
$sesion = $notice->addChild('session');
foreach ($_SESSION as $name => $var) {
if (is_array($var) || is_object($var)) {
$var = json_encode($var);
}
$session->addChild('var', htmlentities($var, ENT_QUOTES, 'UTF-8'))
->addAttribute('key', $name);
}
}
}
$server = $notice->addChild('server-environment');
$server->{'project-root'} = LITHIUM_APP_PATH;
$server->{'environment-name'} = Environment::get();
$api->post('/notifier_api/v2/notices', $notice->asXml(), array(
'type' => 'text/xml'
));
} catch (Exception $e) {
error_log("error while handling error - {$e->getMessage()} on line {$e->getLine()} of {$e->getFile()}");
error_log($msg);
}
return $return;
};
ErrorHandler::config(array('default' => array(
'handler' => function($info, $params = null) use ($notifier) {
$result = $notifier($info, $params);
extract($result);
if (!empty($_SERVER['HTTP_HOST'])) {
echo "Oops... our server made a boo-boo. Sorry! <a href=\"\" onclick=\"window.location.reload();return false;\">Click here to continue</a>.";
}
return true;
}
)));
ErrorHandler::run();
ErrorHandler::apply('lithium\action\Dispatcher::run', array(), function($info, $params) use ($notifier) {
$result = $notifier($info, $params);
extract($result);
$exception = $info['exception'];
$code = $exception->getCode();
$response = new Response(array(
'request' => $params['request'],
'status' => $code
));
try {
if (Environment::is('production')) {
Media::render($response, compact('info', 'params'), array(
'controller' => 'pages',
'template' => 'uh-oh',
'layout' => 'error-production',
'request' => $params['request']
));
} else {
Media::render($response, compact('info', 'params'), array(
'controller' => '_errors',
'template' => 'development',
'layout' => 'error',
'request' => $params['request']
));
}
} catch (Exception $e) {
// just in case something wrong happened while rendering
$webroot = Libraries::get(true, 'path') . '/webroot';
switch ($code) {
case 404:
$file = "{$webroot}/4oh4.html";
break;
default:
$file = "{$webroot}/uh-oh.html";
break;
}
if (file_exists($file)) {
$response->body(file_get_contents($file));
} else {
$response->body(
"Oops... our server made a boo-boo. Sorry! " .
"<a href=\"\" onclick=\"window.location.reload();return false;\">" .
"Click here to continue</a>."
);
}
}
return $response;
});
$consoleNotifier = function($info, $params) use ($notifier) {
$result = $notifier($info, $params);
extract($result);
$exception = $info['exception'];
$code = $exception->getCode();
$response = new ConsoleResponse(array(
'request' => $params['request'],
'status' => $code
));
$response->error($msg);
return $response;
};
ErrorHandler::apply('lithium\console\Dispatcher::run', array(), $consoleNotifier);
ErrorHandler::apply('lithium\console\Dispatcher::_callable', array(), $consoleNotifier);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment