Skip to content

Commit

Permalink
added the ErrorHandler module and updated the error approach
Browse files Browse the repository at this point in the history
  • Loading branch information
ValeriaMaltseva committed Nov 29, 2024
1 parent d67817d commit 41109ff
Show file tree
Hide file tree
Showing 11 changed files with 2,043 additions and 1,908 deletions.
58 changes: 0 additions & 58 deletions assets/js/src/core/hooks/use-api-error-handler.tsx

This file was deleted.

13 changes: 9 additions & 4 deletions assets/js/src/core/modules/app/app-loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import {
useMercureCreateCookieMutation
} from '../asset/editor/types/folder/tab-manager/tabs/list/toolbar/tools/mercure-api-slice.gen'
import { Content } from '@Pimcore/components/content/content'
import { useApiErrorHandler } from '@Pimcore/hooks/use-api-error-handler'
import { GlobalStyles } from '@Pimcore/styles/global.styles'
import { useAlertModal } from '@Pimcore/components/modal/alert-modal/hooks/use-alert-modal'
import { ErrorModalService } from '@Pimcore/modules/app/error-handler/services/error-modal-service'
import { trackError } from '@Pimcore/modules/app/error-handler/error-handler'

export interface IAppLoaderProps {
children: React.ReactNode
Expand All @@ -39,15 +41,18 @@ export const AppLoader = (props: IAppLoaderProps): React.JSX.Element => {
const [translations] = useTranslationGetCollectionMutation()
const [fetchMercureCookie] = useMercureCreateCookieMutation()

const { track } = useApiErrorHandler()
const modal = useAlertModal()

// Register the modal instance to allow centralized error message display throughout the project
ErrorModalService.setModalInstance(modal)

async function initLoadUser (): Promise<any> {
const userFetcher = dispatch(api.endpoints.userGetCurrentInformation.initiate())
await fetchMercureCookie()

userFetcher
.then(({ data, isSuccess, isError, error }) => {
isError && track(error)
isError && trackError({ errorType: 'API_ERROR', errorData: error })

if (isSuccess && data !== undefined) {
dispatch(setUser(data))
Expand All @@ -63,7 +68,7 @@ export const AppLoader = (props: IAppLoaderProps): React.JSX.Element => {

settingsFetcher
.then(({ data, isSuccess, isError, error }) => {
isError && track(error)
isError && trackError({ errorType: 'API_ERROR', errorData: error })

if (isSuccess && data !== undefined) {
dispatch(setSettings(data))
Expand Down
49 changes: 49 additions & 0 deletions assets/js/src/core/modules/app/error-handler/classes/api-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { isEmpty, isString } from 'lodash'
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'
import type { SerializedError } from '@reduxjs/toolkit'

type ApiErrorData = FetchBaseQueryError | SerializedError

interface IApiErrorDetails {
detail: string
message: string
}

const DEFAULT_ERROR_CONTENT = 'Something went wrong.'

export class ApiError extends Error {
private readonly errorData: ApiErrorData

constructor (errorData: ApiErrorData) {
super()

this.errorData = errorData
}

public getContent (): string {
if (!isEmpty(this.errorData)) {
if ('data' in this.errorData && !isEmpty((this.errorData.data as IApiErrorDetails)?.message)) {
return (this.errorData.data as IApiErrorDetails)?.message
}

if ('error' in this.errorData && isString(this.errorData.error)) {
return this.errorData.error
}
}

return DEFAULT_ERROR_CONTENT
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

export class GeneralError extends Error {
private readonly errorMessage: string

constructor (message: string) {
super()

this.errorMessage = message
}

public getContent (): string {
return this.errorMessage
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

export enum ErrorTypes {
API_ERROR = 'API_ERROR',
GENERAL_ERROR = 'GENERAL_ERROR'
}
48 changes: 48 additions & 0 deletions assets/js/src/core/modules/app/error-handler/error-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'
import type { SerializedError } from '@reduxjs/toolkit'
import { isFunction } from 'lodash'
import { ErrorModalService } from '@Pimcore/modules/app/error-handler/services/error-modal-service'
import { GeneralError } from '@Pimcore/modules/app/error-handler/classes/general-error'
import { ApiError } from '@Pimcore/modules/app/error-handler/classes/api-error'
import { type ErrorTypes } from '@Pimcore/modules/app/error-handler/constants/errorTypes'

interface ITrackProps {
errorType: keyof typeof ErrorTypes
errorData: FetchBaseQueryError | SerializedError | string
}

const ERROR_HANDLERS_LIST: Record<ITrackProps['errorType'], (errorData: ITrackProps['errorData']) => void> = {
API_ERROR: (errorData: FetchBaseQueryError | SerializedError) => {
const error = new ApiError(errorData)

ErrorModalService.showError(error.getContent())
},
GENERAL_ERROR: (errorData: string) => {
const error = new GeneralError(errorData)

ErrorModalService.showError(error.getContent())
}
}

export const trackError = ({ errorType, errorData }: ITrackProps): void => {
const errorHandler = ERROR_HANDLERS_LIST[errorType]

if (isFunction(errorHandler)) {
errorHandler(errorData)
} else {
console.error(`Unhandled error type: ${errorType}`)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { isEmpty } from 'lodash'

interface IErrorModalServiceReturn {
setModalInstance: (modal: any) => void
showError: (content: string) => void
}

export const ErrorModalService = ((): IErrorModalServiceReturn => {
let modalInstance: any = null

const setModalInstance = (modal: any): void => {
modalInstance = modal
}

const showError = (content: string): void => {
if (isEmpty(modalInstance)) {
throw new Error('ErrorModalService: Modal instance is not set. Call setModalInstance first.')
}

modalInstance.error({ content })
}

return {
setModalInstance,
showError
}
})()
14 changes: 0 additions & 14 deletions public/build/a946d68d-b560-4419-9193-270ffd330528/entrypoints.json

This file was deleted.

Loading

0 comments on commit 41109ff

Please sign in to comment.