From f7aff4ab27bae3cd904c9e37f947b699ae5c2c22 Mon Sep 17 00:00:00 2001 From: Tushar Ahire Date: Thu, 14 Nov 2024 16:09:21 +0530 Subject: [PATCH 1/7] fix: adds try catch redirects to error page --- src/application/services/useNote.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/application/services/useNote.ts b/src/application/services/useNote.ts index 938fbc0f..53b412f5 100644 --- a/src/application/services/useNote.ts +++ b/src/application/services/useNote.ts @@ -166,12 +166,16 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt /** * @todo try-catch domain errors */ - const response = await noteService.getNoteById(id); - - note.value = response.note; - canEdit.value = response.accessRights.canEdit; - noteTools.value = response.tools; - parentNote.value = response.parentNote; + try { + const response = await noteService.getNoteById(id); + + note.value = response.note; + canEdit.value = response.accessRights.canEdit; + noteTools.value = response.tools; + parentNote.value = response.parentNote; + } catch (error) { + void router.push('/error'); + } } /** From ad06c92646cc38c4205b895482718e144655ef7b Mon Sep 17 00:00:00 2001 From: Tushar Ahire Date: Tue, 19 Nov 2024 21:19:24 +0530 Subject: [PATCH 2/7] fix: separate handling of 4xx and other errors for error pages --- src/application/i18n/messages/en.json | 1 + src/application/router/routes.ts | 12 ++++++++++++ src/application/services/useNote.ts | 7 ++++++- src/domain/entities/errors/ApiError.ts | 16 ++++++++++++++++ src/infrastructure/transport/notes-api/index.ts | 3 ++- 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/domain/entities/errors/ApiError.ts diff --git a/src/application/i18n/messages/en.json b/src/application/i18n/messages/en.json index e1b3baf2..85d7b179 100644 --- a/src/application/i18n/messages/en.json +++ b/src/application/i18n/messages/en.json @@ -177,6 +177,7 @@ "marketplace": "Marketplace", "addTool": "Add tool", "notFound": "Not found", + "unexpectedError": "Unexpected error", "joinTeam": "Join", "authorization": "Authorize", "history": "History", diff --git a/src/application/router/routes.ts b/src/application/router/routes.ts index d242dbf4..a58d5e36 100644 --- a/src/application/router/routes.ts +++ b/src/application/router/routes.ts @@ -195,6 +195,18 @@ const routes: RouteRecordRaw[] = [ code: 404, }, }, + { + path: '/500', + component: ErrorPage, + meta: { + layout: 'fullpage', + pageTitleI18n: 'pages.unexpectedError', + discardTabOnLeave: true, + }, + props: { + code: 500, + }, + }, ]; export default routes; diff --git a/src/application/services/useNote.ts b/src/application/services/useNote.ts index 53b412f5..ebe7367c 100644 --- a/src/application/services/useNote.ts +++ b/src/application/services/useNote.ts @@ -5,6 +5,7 @@ import type { NoteTool } from '@/domain/entities/Note'; import { useRouter, useRoute } from 'vue-router'; import type { NoteDraft } from '@/domain/entities/NoteDraft'; import type EditorTool from '@/domain/entities/EditorTool'; +import ApiError from '@/domain/entities/errors/ApiError'; import useHeader from './useHeader'; import { getTitle } from '@/infrastructure/utils/note'; @@ -174,7 +175,11 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt noteTools.value = response.tools; parentNote.value = response.parentNote; } catch (error) { - void router.push('/error'); + if (error instanceof ApiError) { + void router.push('/500'); + } else { + void router.push('/400'); + } } } diff --git a/src/domain/entities/errors/ApiError.ts b/src/domain/entities/errors/ApiError.ts new file mode 100644 index 00000000..eeb06b1f --- /dev/null +++ b/src/domain/entities/errors/ApiError.ts @@ -0,0 +1,16 @@ +import DomainError from './Base'; + +/** + * Domain error thrown when some resource is not found + */ +export default class ApiError extends DomainError { + /** + * Constructor for ApiError error + * @param message - Error message + * @param statusCode - Error status code + */ + constructor(message: string, public statusCode: number) { + super(message); + this.name = 'ApiError'; + } +} diff --git a/src/infrastructure/transport/notes-api/index.ts b/src/infrastructure/transport/notes-api/index.ts index 175a5bc8..6df6ace2 100644 --- a/src/infrastructure/transport/notes-api/index.ts +++ b/src/infrastructure/transport/notes-api/index.ts @@ -5,6 +5,7 @@ import AuthorizableTransport from '@/infrastructure/transport/authorizable.trans import type JSONValue from '../types/JSONValue'; import UnauthorizedError from '@/domain/entities/errors/Unauthorized'; import NotFoundError from '@/domain/entities/errors/NotFound'; +import ApiError from '@/domain/entities/errors/ApiError'; import type { FilesDto } from '../types/FileDto'; /** @@ -53,7 +54,7 @@ export default class NotesApiTransport extends AuthorizableTransport { case 404: return new NotFoundError(errorText); default: - return new Error(errorText); + return new ApiError(errorText, status); } }, }); From c88dc168c80b644c24a4ff3842b0f1545ddf0f0d Mon Sep 17 00:00:00 2001 From: Tushar Ahire Date: Wed, 20 Nov 2024 21:57:34 +0530 Subject: [PATCH 3/7] fix: handles error using single route --- src/application/i18n/messages/en.json | 2 +- src/application/router/routes.ts | 25 +++++++------------------ src/application/services/useNote.ts | 8 ++++---- src/presentation/pages/Error.vue | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/application/i18n/messages/en.json b/src/application/i18n/messages/en.json index 85d7b179..5010264b 100644 --- a/src/application/i18n/messages/en.json +++ b/src/application/i18n/messages/en.json @@ -176,8 +176,8 @@ "noteSettings": "Note settings", "marketplace": "Marketplace", "addTool": "Add tool", + "error": "Error", "notFound": "Not found", - "unexpectedError": "Unexpected error", "joinTeam": "Join", "authorization": "Authorize", "history": "History", diff --git a/src/application/router/routes.ts b/src/application/router/routes.ts index a58d5e36..9c14883c 100644 --- a/src/application/router/routes.ts +++ b/src/application/router/routes.ts @@ -181,31 +181,20 @@ const routes: RouteRecordRaw[] = [ }, /** - * 404 page + * error page */ { - path: '/:pathMatch(.*)*', + path: '/error', component: ErrorPage, meta: { layout: 'fullpage', - pageTitleI18n: 'pages.notFound', + pageTitleI18n: 'pages.error', discardTabOnLeave: true, }, - props: { - code: 404, - }, - }, - { - path: '/500', - component: ErrorPage, - meta: { - layout: 'fullpage', - pageTitleI18n: 'pages.unexpectedError', - discardTabOnLeave: true, - }, - props: { - code: 500, - }, + props: route => ({ + code: route.query.code, + customMessage: route.query.message, + }), }, ]; diff --git a/src/application/services/useNote.ts b/src/application/services/useNote.ts index ebe7367c..be2eb972 100644 --- a/src/application/services/useNote.ts +++ b/src/application/services/useNote.ts @@ -5,7 +5,7 @@ import type { NoteTool } from '@/domain/entities/Note'; import { useRouter, useRoute } from 'vue-router'; import type { NoteDraft } from '@/domain/entities/NoteDraft'; import type EditorTool from '@/domain/entities/EditorTool'; -import ApiError from '@/domain/entities/errors/ApiError'; +import NotFoundError from '@/domain/entities/errors/NotFound'; import useHeader from './useHeader'; import { getTitle } from '@/infrastructure/utils/note'; @@ -175,10 +175,10 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt noteTools.value = response.tools; parentNote.value = response.parentNote; } catch (error) { - if (error instanceof ApiError) { - void router.push('/500'); + if (error instanceof NotFoundError) { + void router.push('/error?code=404'); } else { - void router.push('/400'); + void router.push('/error'); } } } diff --git a/src/presentation/pages/Error.vue b/src/presentation/pages/Error.vue index ec704511..c22787e8 100644 --- a/src/presentation/pages/Error.vue +++ b/src/presentation/pages/Error.vue @@ -12,6 +12,12 @@