Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Expect the Un-expected: How to Handle Errors Gracefully

Expect the Un-expected: How to Handle Errors Gracefully

Even though you tested your application perfectly, errors and bugs will still happen in production, especially if other services or databases go down or are under high load. Thus it is very important to see errors happening and to be able to react to them quickly. In this session we'll introduce you to efficient ways for monitoring and logging for errors and show how you can handle them if they happen, covering deployment strategies, using intelligent circuit breakers, and gracefully reducing functionality. The session will give examples and recommendations so that you can quickly get started with implementing these.

Bastian Hofmann

October 24, 2017
Tweet

More Decks by Bastian Hofmann

Other Decks in Programming

Transcript

  1. [24-Oct-2017 18:18:24 UTC] PHP Fatal error: Uncaught Exception: error in

    /Users/ bastian/error_test_php/index.php:5 Stack trace: #0 /Users/bastian/error_test_php/index.php(8): index() #1 {main} thrown in /Users/bastian/error_test_php/index.php on line 5
  2. try { // your complex potentially failing code } catch

    (\Throwable $e) { // do some error handling }
  3. try { // your complex potentially failing code } catch

    (SomeException $e) { // do some error handling }
  4. try { // your complex potentially failing code } catch

    (SomeException $e) { // do some error handling } catch (OtherError $e) { // do some error handling }
  5. try { // your complex potentially failing code } catch

    (SomeException | OtherError $e) { // do some error handling }
  6. bool error_log ( string $message [, int $message_type = 0

    [, string $destination [, string $extra_headers ]]] )
  7. <?php use Monolog\Logger; use Monolog\Handler\StreamHandler; // create a log channel

    $log = new Logger('name'); $log->pushHandler( new StreamHandler( 'path/to/your.log', Logger::WARNING ) ); // add records to the log $log->addWarning('Foo'); $log->addError('Bar');
  8. set_error_handler( function($errno, $msg, $file, $line) { $e = new \Exception();

    $error = [ 'type' => $errno, 'message' => $msg, 'file' => $file, 'line' => $line, 'trace' => $e->getTrace(), ]; error_log(json_encode($error)); return true; });
  9. set_error_handler( function($errno, $msg, $file, $line) { switch ($errno) { case

    E_RECOVERABLE_ERROR: case E_USER_ERROR: throw new \ErrorException($msg, null, $errno, $file, $line); case E_WARNING: case E_USER_WARNING: case E_CORE_WARNING: case E_COMPILE_WARNING: throw new WarningException($msg, null, $errno, $file, $line); case E_NOTICE: case E_USER_NOTICE: throw new NoticeException($msg, null, $errno, $file, $line); case E_STRICT: throw new StrictException($msg, null, $errno, $file, $line); } return true; }); $a = []; try { $b = $a['doesNotExist']; } catch (NoticeException $e) { }
  10. http service http service http service http service create unique

    trace_id for request user request trace_id trace_id trace_id trace_id log log log log log gateway service
  11. input { file { type => "error" path => [

    "/var/logs/php/*.log" ] add_field => [ "severity", "error" ] } }
  12. input {
 rabbitmq {
 queue => "logs"
 host => "amqp.host"


    exchange => "ls_exchange"
 exclusive => false
 }
 }
  13. output {
 elasticsearch {
 embedded => false
 bind_host => "localhost"


    bind_port => "9305"
 host => "localhost"
 cluster => "logs"
 }
 }
  14. Service A Service B Error Circuit Breaker Status: -> open

    Error rate: > threshold Test if still failing
  15. Service A Service B 200 OK Circuit Breaker Status: ->

    close Error rate: 0 Test if still failing