3 * @copyright Copyright (C) 2010-2023, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Module\Special;
24 use Friendica\App\Arguments;
25 use Friendica\App\Request;
26 use Friendica\Core\L10n;
27 use Friendica\Core\Renderer;
28 use Friendica\Core\Session\Model\UserSession;
29 use Friendica\Core\System;
30 use Psr\Log\LoggerInterface;
33 * This special module displays HTTPException when they are thrown in modules.
35 * @package Friendica\Module\Special
41 /** @var LoggerInterface */
46 protected $isSiteAdmin;
52 public function __construct(L10n $l10n, LoggerInterface $logger, Arguments $args, UserSession $session, Request $request, array $server = [])
54 $this->logger = $logger;
57 $this->isSiteAdmin = $session->isSiteAdmin();
58 $this->server = $server;
59 $this->requestId = $request->getRequestId();
63 * Generates the necessary template variables from the caught HTTPException.
65 * Fills in the blanks if title or descriptions aren't provided by the exception.
67 * @param \Friendica\Network\HTTPException $e
69 * @return array ['$title' => ..., '$description' => ...]
71 private function getVars(\Friendica\Network\HTTPException $e)
73 // Explanations are mostly taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
75 '$title' => $e->getDescription() ?: 'Error ' . $e->getCode(),
76 '$message' => $e->getMessage() ?: $e->getExplanation(),
77 '$back' => $this->l10n->t('Go back'),
78 '$stack_trace' => $this->l10n->t('Stack trace:'),
79 '$request_id' => $this->requestId,
82 if ($this->isSiteAdmin) {
83 $vars['$thrown'] = $this->l10n->t('Exception thrown in %s:%d', $e->getFile(), $e->getLine());
84 $vars['$trace'] = $e->getTraceAsString();
91 * Displays a bare message page with no theming at all.
93 * @param \Friendica\Network\HTTPException $e
97 public function rawContent(\Friendica\Network\HTTPException $e)
101 if ($e->getCode() >= 400) {
102 $vars = $this->getVars($e);
104 $tpl = Renderer::getMarkupTemplate('http_status.tpl');
105 $content = Renderer::replaceMacros($tpl, $vars);
106 } catch (\Exception $e) {
107 $vars = array_map('htmlentities', $vars);
108 $content = "<h1>{$vars['$title']}</h1><p>{$vars['$message']}</p>";
109 if ($this->isSiteAdmin) {
110 $content .= "<p>{$vars['$thrown']}</p>";
111 $content .= "<pre>{$vars['$trace']}</pre>";
116 System::httpError($e->getCode(), $e->getDescription(), $content);
120 * Returns a content string that can be integrated in the current theme.
122 * @param \Friendica\Network\HTTPException $e
127 public function content(\Friendica\Network\HTTPException $e): string
129 if ($e->getCode() >= 400) {
130 $this->logger->debug('Exit with error',
132 'code' => $e->getCode(),
133 'description' => $e->getDescription(),
134 'query' => $this->args->getQueryString(),
135 'callstack' => System::callstack(20),
136 'method' => $this->args->getMethod(),
137 'agent' => $this->server['HTTP_USER_AGENT'] ?? ''
141 $tpl = Renderer::getMarkupTemplate('exception.tpl');
143 return Renderer::replaceMacros($tpl, $this->getVars($e));