diff options
| author | kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> | 2023-04-12 12:52:14 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-12 12:52:14 +0900 |
| commit | 49749b46c4c8914947e0950069bcf4431f157c4f (patch) | |
| tree | 6af5d7439b5fc17772b02d1bdc5566b4789fe615 /packages/backend/src/server/web | |
| parent | feat: role timeline (diff) | |
| download | misskey-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.ts | 14 | ||||
| -rw-r--r-- | packages/backend/src/server/web/ClientServerService.ts | 24 | ||||
| -rw-r--r-- | packages/backend/src/server/web/error.css | 110 | ||||
| -rw-r--r-- | packages/backend/src/server/web/views/error.pug | 65 |
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 |