Elgg  Version 6.2
ExceptionHandler.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Application;
4 
8 use Elgg\Traits\Loggable;
9 use Psr\Log\LogLevel;
10 use Symfony\Component\HttpFoundation\JsonResponse;
11 use Symfony\Component\HttpFoundation\RedirectResponse;
12 use Symfony\Component\HttpFoundation\Response;
13 
20 
21  use Loggable;
22 
39  public function __invoke(\Throwable $exception): void {
40  $this->log(LogLevel::CRITICAL, $exception);
41 
42  // Wipe any existing output buffer
43  ob_end_clean();
44 
45  $request = Request::createFromGlobals();
46  $headers = [
47  'Cache-Control' => 'no-store, must-revalidate',
48  'Expires' => 'Fri, 05 Feb 1982 00:00:00 -0500',
49  ];
50 
51  if ($exception instanceof InstallationException) {
52  $response = new RedirectResponse('/install.php', ELGG_HTTP_TEMPORARY_REDIRECT, $headers);
53  $response->prepare($request);
54 
55  $response->send();
56 
57  return;
58  }
59 
61  $now = time();
62 
63  if (!$app || !$app->internal_services) {
64  $msg = "Exception loading Elgg core. Check log at time {$now}";
65  $response = new Response($msg, ELGG_HTTP_INTERNAL_SERVER_ERROR, $headers);
66  $response->prepare($request);
67 
68  $response->send();
69 
70  return;
71  }
72 
73  $services = $app->internal_services;
74  if ($services->responseFactory->getSentResponse() !== null) {
75  return;
76  }
77 
78  try {
79  // allow custom scripts to trigger on exception
80  // value in settings.php should be a system path to a file to include
81  $exception_include = $services->config->exception_include;
82 
83  if ($exception_include && is_file($exception_include)) {
84  ob_start();
85 
86  // don't isolate, these scripts may use the local $exception var.
87  include $exception_include;
88 
89  $exception_output = ob_get_clean();
90 
91  // if content is returned from the custom handler we will output
92  // that instead of our default failsafe view
93  if (!empty($exception_output)) {
94  $response = new Response($exception_output, ELGG_HTTP_INTERNAL_SERVER_ERROR, $headers);
95  $response->prepare($request);
96 
97  $response->send();
98 
99  return;
100  }
101  }
102 
103  if (Application::isCli()) {
104  // An error has already been logged
105  return;
106  }
107 
108  if ($services->request->isXmlHttpRequest()) {
109  $services->views->setViewtype('json');
110  $response = new JsonResponse(null, ELGG_HTTP_INTERNAL_SERVER_ERROR, $headers);
111  } else {
112  $services->views->setViewtype('failsafe');
114  }
115 
116  $body = elgg_view('messages/exceptions/exception', [
117  'object' => $exception,
118  'ts' => $now,
119  ]);
120 
121  $response->prepare($services->request);
122  $response->setContent(elgg_view_page(elgg_echo('exception:title'), $body));
123  $response->send();
124  } catch (\Throwable $e) {
125  $now = time();
126 
127  $this->log(LogLevel::CRITICAL, $e);
128 
129  $msg = "Fatal error in exception handler. Check log for Exception at time {$now}";
130 
131  $response = new Response($msg, ELGG_HTTP_INTERNAL_SERVER_ERROR, $headers);
132  $response->prepare($request);
133  $response->send();
134  }
135  }
136 }
log($level, $message, array $context=[])
Log a message.
Definition: Loggable.php:58
$body
Definition: useradd.php:55
Handler for uncaught exceptions.
__invoke(\Throwable $exception)
Intercepts, logs, and displays uncaught exceptions.
static $_instance
Reference to the loaded Application.
Definition: Application.php:71
static isCli()
Is application running in CLI.
Thrown when there is a major problem with the installation.
Elgg HTTP request.
Definition: Request.php:17
const ELGG_HTTP_INTERNAL_SERVER_ERROR
Definition: constants.php:91
const ELGG_HTTP_TEMPORARY_REDIRECT
Definition: constants.php:62
elgg_echo(string $message_key, array $args=[], string $language='')
Elgg language module Functions to manage language and translations.
Definition: languages.php:17
elgg_view_page(string $title, string|array $body, string $page_shell='default', array $vars=[])
Assembles and outputs a full page.
Definition: views.php:235
elgg_view(string $view, array $vars=[], string $viewtype='')
Return a parsed view.
Definition: views.php:156
$request
Definition: livesearch.php:12
$headers
Definition: section.php:21
$exception
Definition: error.php:15
$response
Definition: content.php:10