summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/web
diff options
context:
space:
mode:
authorkakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>2023-04-12 12:52:14 +0900
committerGitHub <noreply@github.com>2023-04-12 12:52:14 +0900
commit49749b46c4c8914947e0950069bcf4431f157c4f (patch)
tree6af5d7439b5fc17772b02d1bdc5566b4789fe615 /packages/backend/src/server/web
parentfeat: role timeline (diff)
downloadmisskey-49749b46c4c8914947e0950069bcf4431f157c4f.tar.gz
misskey-49749b46c4c8914947e0950069bcf4431f157c4f.tar.bz2
misskey-49749b46c4c8914947e0950069bcf4431f157c4f.zip
feat(server): Misskey Webでユーザーフレンドリーなエラーページを出す (#10590)
* (add) user-friendly error page * Update CHANGELOG.md * (add) cache-control header * Add ClientLoggerService * Log params and query * remove error stack on client * fix pug * 文面を調整 * :art] --------- Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Diffstat (limited to 'packages/backend/src/server/web')
-rw-r--r--packages/backend/src/server/web/ClientLoggerService.ts14
-rw-r--r--packages/backend/src/server/web/ClientServerService.ts24
-rw-r--r--packages/backend/src/server/web/error.css110
-rw-r--r--packages/backend/src/server/web/views/error.pug65
4 files changed, 213 insertions, 0 deletions
diff --git a/packages/backend/src/server/web/ClientLoggerService.ts b/packages/backend/src/server/web/ClientLoggerService.ts
new file mode 100644
index 0000000000..6a882aa766
--- /dev/null
+++ b/packages/backend/src/server/web/ClientLoggerService.ts
@@ -0,0 +1,14 @@
+import { Injectable } from '@nestjs/common';
+import type Logger from '@/logger.js';
+import { LoggerService } from '@/core/LoggerService.js';
+
+@Injectable()
+export class ClientLoggerService {
+ public logger: Logger;
+
+ constructor(
+ private loggerService: LoggerService,
+ ) {
+ this.logger = this.loggerService.getLogger('client');
+ }
+}
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts
index 99ae1b7af6..50b23a0682 100644
--- a/packages/backend/src/server/web/ClientServerService.ts
+++ b/packages/backend/src/server/web/ClientServerService.ts
@@ -1,6 +1,7 @@
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { Inject, Injectable } from '@nestjs/common';
+import { v4 as uuid } from 'uuid';
import { createBullBoard } from '@bull-board/api';
import { BullAdapter } from '@bull-board/api/bullAdapter.js';
import { FastifyAdapter } from '@bull-board/fastify';
@@ -26,6 +27,7 @@ import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityServi
import { ClipEntityService } from '@/core/entities/ClipEntityService.js';
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
import type { ChannelsRepository, ClipsRepository, FlashsRepository, GalleryPostsRepository, NotesRepository, PagesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
+import type Logger from '@/logger.js';
import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js';
import { FlashEntityService } from '@/core/entities/FlashEntityService.js';
@@ -34,6 +36,7 @@ import manifest from './manifest.json' assert { type: 'json' };
import { FeedService } from './FeedService.js';
import { UrlPreviewService } from './UrlPreviewService.js';
import type { FastifyInstance, FastifyPluginOptions, FastifyReply } from 'fastify';
+import { ClientLoggerService } from './ClientLoggerService.js';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
@@ -46,6 +49,8 @@ const viteOut = `${_dirname}/../../../../../built/_vite_/`;
@Injectable()
export class ClientServerService {
+ private logger: Logger;
+
constructor(
@Inject(DI.config)
private config: Config,
@@ -85,6 +90,7 @@ export class ClientServerService {
private urlPreviewService: UrlPreviewService,
private feedService: FeedService,
private roleService: RoleService,
+ private clientLoggerService: ClientLoggerService,
@Inject('queue:system') public systemQueue: SystemQueue,
@Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue,
@@ -649,6 +655,24 @@ export class ClientServerService {
return await renderBase(reply);
});
+ fastify.setErrorHandler(async (error, request, reply) => {
+ const errId = uuid();
+ this.clientLoggerService.logger.error(`Internal error occured in ${request.routerPath}: ${error.message}`, {
+ path: request.routerPath,
+ params: request.params,
+ query: request.query,
+ code: error.name,
+ stack: error.stack,
+ id: errId,
+ });
+ reply.code(500);
+ reply.header('Cache-Control', 'max-age=10, must-revalidate');
+ return await reply.view('error', {
+ code: error.code,
+ id: errId,
+ });
+ });
+
done();
}
}
diff --git a/packages/backend/src/server/web/error.css b/packages/backend/src/server/web/error.css
new file mode 100644
index 0000000000..ab913f7a9f
--- /dev/null
+++ b/packages/backend/src/server/web/error.css
@@ -0,0 +1,110 @@
+* {
+ font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
+}
+
+#misskey_app,
+#splash {
+ display: none !important;
+}
+
+body,
+html {
+ background-color: #222;
+ color: #dfddcc;
+ justify-content: center;
+ margin: auto;
+ padding: 10px;
+ text-align: center;
+}
+
+button {
+ border-radius: 999px;
+ padding: 0px 12px 0px 12px;
+ border: none;
+ cursor: pointer;
+ margin-bottom: 12px;
+}
+
+.button-big {
+ background: linear-gradient(90deg, rgb(134, 179, 0), rgb(74, 179, 0));
+ line-height: 50px;
+}
+
+.button-big:hover {
+ background: rgb(153, 204, 0);
+}
+
+.button-small {
+ background: #444;
+ line-height: 40px;
+}
+
+.button-small:hover {
+ background: #555;
+}
+
+.button-label-big {
+ color: #222;
+ font-weight: bold;
+ font-size: 20px;
+ padding: 12px;
+}
+
+.button-label-small {
+ color: rgb(153, 204, 0);
+ font-size: 16px;
+ padding: 12px;
+}
+
+a {
+ color: rgb(134, 179, 0);
+ text-decoration: none;
+}
+
+p,
+li {
+ font-size: 16px;
+}
+
+.dont-worry,
+#msg {
+ font-size: 18px;
+}
+
+.icon-warning {
+ color: #dec340;
+ height: 4rem;
+ padding-top: 2rem;
+}
+
+h1 {
+ font-size: 32px;
+}
+
+code {
+ display: block;
+ font-family: Fira, FiraCode, monospace;
+ background: #333;
+ padding: 0.5rem 1rem;
+ max-width: 40rem;
+ border-radius: 10px;
+ justify-content: center;
+ margin: auto;
+ white-space: pre-wrap;
+ word-break: break-word;
+}
+
+summary {
+ cursor: pointer;
+}
+
+summary > * {
+ display: inline;
+ white-space: pre-wrap;
+}
+
+@media screen and (max-width: 500px) {
+ details {
+ width: 50%;
+ }
+} \ No newline at end of file
diff --git a/packages/backend/src/server/web/views/error.pug b/packages/backend/src/server/web/views/error.pug
new file mode 100644
index 0000000000..b177ae4110
--- /dev/null
+++ b/packages/backend/src/server/web/views/error.pug
@@ -0,0 +1,65 @@
+doctype html
+
+//
+ -
+ _____ _ _
+ | |_|___ ___| |_ ___ _ _
+ | | | | |_ -|_ -| '_| -_| | |
+ |_|_|_|_|___|___|_,_|___|_ |
+ |___|
+ Thank you for using Misskey!
+ If you are reading this message... how about joining the development?
+ https://github.com/misskey-dev/misskey
+
+
+html
+
+ head
+ meta(charset='utf-8')
+ meta(name='viewport' content='width=device-width, initial-scale=1')
+ meta(name='application-name' content='Misskey')
+ meta(name='referrer' content='origin')
+
+ title
+ block title
+ = 'An error has occurred... | Misskey'
+
+ style
+ include ../error.css
+
+body
+ svg.icon-warning(xmlns="http://www.w3.org/2000/svg", viewBox="0 0 24 24", stroke-width="2", stroke="currentColor", fill="none", stroke-linecap="round", stroke-linejoin="round")
+ path(stroke="none", d="M0 0h24v24H0z", fill="none")
+ path(d="M12 9v2m0 4v.01")
+ path(d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75")
+
+ h1 An error has occurred!
+
+ button.button-big(onclick="location.reload();")
+ span.button-label-big Refresh
+
+ p.dont-worry Don't worry, it's (probably) not your fault.
+
+ p If reloading after a period of time does not resolve the problem, contact the server administrator with the following ERROR ID.
+
+ div#errors
+ code.
+ ERROR CODE: #{code}
+ ERROR ID: #{id}
+
+ p You may also try the following options:
+
+ p Update your os and browser.
+ p Disable an adblocker.
+
+ a(href="/flush")
+ button.button-small
+ span.button-label-small Clear preferences and cache
+ br
+ a(href="/cli")
+ button.button-small
+ span.button-label-small Start the simple client
+ br
+ a(href="/bios")
+ button.button-small
+ span.button-label-small Start the repair tool