From 207b589dd5273a7cea3127fcf19489ad9d51e286 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 16 Mar 2026 16:33:41 +0100 Subject: [PATCH] refactor: extract ensureError and getErrorMessage helpers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Replace 61 duplicated error coercion patterns across 18 files: - 34× 'error instanceof Error ? error : new Error(String(error))' → ensureError(error) - 27× 'error instanceof Error ? error.message : String(error)' → getErrorMessage(error) New helpers in src/utils/ErrorUtils.ts, exported via barrel. --- src/charging-station/ChargingStation.ts | 15 ++++++------ src/charging-station/ChargingStationWorker.ts | 4 ++-- src/charging-station/IdTagsCache.ts | 10 +++----- .../ChargingStationWorkerBroadcastChannel.ts | 11 +++++++-- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 9 +++---- .../ocpp/2.0/OCPP20CertificateManager.ts | 3 ++- .../ocpp/OCPPRequestService.ts | 7 +++--- .../ocpp/auth/services/OCPPAuthServiceImpl.ts | 12 +++++----- .../ocpp/auth/strategies/LocalAuthStrategy.ts | 24 +++++++++---------- .../auth/strategies/RemoteAuthStrategy.ts | 18 +++++++------- .../ui-server/UIHttpServer.ts | 4 ++-- .../ui-server/UIServerUtils.ts | 8 ++----- .../ui-services/AbstractUIService.ts | 21 ++++++++++------ src/performance/storage/JsonFileStorage.ts | 14 +++++++---- src/performance/storage/MikroOrmStorage.ts | 14 ++++------- src/performance/storage/MongoDBStorage.ts | 14 ++++------- src/utils/Configuration.ts | 6 ++--- src/utils/ErrorUtils.ts | 6 +++++ src/utils/FileUtils.ts | 14 ++++------- src/utils/index.ts | 2 ++ 20 files changed, 110 insertions(+), 106 deletions(-) diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 38962392..a70705da 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -84,9 +84,11 @@ import { convertToDate, convertToInt, DCElectricUtils, + ensureError, exponentialDelay, formatDurationMilliSeconds, formatDurationSeconds, + getErrorMessage, getWebSocketCloseEventStatusString, handleFileException, isEmpty, @@ -1356,7 +1358,7 @@ export class ChargingStation extends EventEmitter { handleFileException( this.configurationFile, FileType.ChargingStationConfiguration, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix() ) if ( @@ -1628,7 +1630,7 @@ export class ChargingStation extends EventEmitter { handleFileException( this.templateFile, FileType.ChargingStationTemplate, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix() ) } @@ -2214,10 +2216,7 @@ export class ChargingStation extends EventEmitter { const ocppError = error instanceof OCPPError ? error - : new OCPPError( - ErrorType.INTERNAL_ERROR, - error instanceof Error ? error.message : String(error) - ) + : new OCPPError(ErrorType.INTERNAL_ERROR, getErrorMessage(error)) switch (messageType) { case MessageType.CALL_ERROR_MESSAGE: case MessageType.CALL_RESULT_MESSAGE: @@ -2451,7 +2450,7 @@ export class ChargingStation extends EventEmitter { handleFileException( this.configurationFile, FileType.ChargingStationConfiguration, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix() ) }) @@ -2466,7 +2465,7 @@ export class ChargingStation extends EventEmitter { handleFileException( this.configurationFile, FileType.ChargingStationConfiguration, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix() ) } diff --git a/src/charging-station/ChargingStationWorker.ts b/src/charging-station/ChargingStationWorker.ts index 58f63ff9..37d0406a 100644 --- a/src/charging-station/ChargingStationWorker.ts +++ b/src/charging-station/ChargingStationWorker.ts @@ -6,7 +6,7 @@ import { ThreadWorker } from 'poolifier' import type { ChargingStationInfo, ChargingStationWorkerData } from '../types/index.js' import { BaseError } from '../exception/index.js' -import { Configuration } from '../utils/index.js' +import { Configuration, getErrorMessage } from '../utils/index.js' import { type WorkerDataError, type WorkerMessage, WorkerMessageEvents } from '../worker/index.js' import { ChargingStation } from './ChargingStation.js' @@ -64,7 +64,7 @@ if (Configuration.workerPoolInUse()) { parentPort?.postMessage({ data: { event, - message: error instanceof Error ? error.message : String(error), + message: getErrorMessage(error), name: error instanceof Error ? error.name : 'UnknownError', stack: error instanceof Error ? error.stack : undefined, }, diff --git a/src/charging-station/IdTagsCache.ts b/src/charging-station/IdTagsCache.ts index dde5d8d1..8e982e0d 100644 --- a/src/charging-station/IdTagsCache.ts +++ b/src/charging-station/IdTagsCache.ts @@ -4,6 +4,7 @@ import type { ChargingStation } from './ChargingStation.js' import { FileType, IdTagDistribution } from '../types/index.js' import { + ensureError, handleFileException, isNotEmptyString, logger, @@ -125,12 +126,7 @@ export class IdTagsCache { try { return JSON.parse(readFileSync(file, 'utf8')) as string[] } catch (error) { - handleFileException( - file, - FileType.Authorization, - error instanceof Error ? error : new Error(String(error)), - this.logPrefix(file) - ) + handleFileException(file, FileType.Authorization, ensureError(error), this.logPrefix(file)) } } return [] @@ -187,7 +183,7 @@ export class IdTagsCache { handleFileException( file, FileType.Authorization, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix(file), { throwError: false, diff --git a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts index 3b173a76..ba414170 100644 --- a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts @@ -59,7 +59,14 @@ import { type StopTransactionRequest, type StopTransactionResponse, } from '../../types/index.js' -import { Constants, convertToInt, isAsyncFunction, isEmpty, logger } from '../../utils/index.js' +import { + Constants, + convertToInt, + getErrorMessage, + isAsyncFunction, + isEmpty, + logger, +} from '../../utils/index.js' import { getConfigurationKey } from '../ConfigurationKeyUtils.js' import { buildMeterValue } from '../ocpp/index.js' import { WorkerBroadcastChannel } from './WorkerBroadcastChannel.js' @@ -678,7 +685,7 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne responsePayload = { command, errorDetails: error instanceof OCPPError ? error.details : undefined, - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, hashId: this.chargingStation.stationInfo?.hashId, requestPayload, diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index a530bc27..54b8c95d 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -106,6 +106,7 @@ import { Configuration, convertToDate, convertToInt, + ensureError, formatDurationMilliSeconds, handleIncomingRequestError, isEmpty, @@ -657,7 +658,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { return handleIncomingRequestError( chargingStation, OCPP16IncomingRequestCommand.CANCEL_RESERVATION, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED, } @@ -918,7 +919,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { return handleIncomingRequestError( chargingStation, OCPP16IncomingRequestCommand.DATA_TRANSFER, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { errorResponse: OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_REJECTED } )! } @@ -1162,7 +1163,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { return handleIncomingRequestError( chargingStation, OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { errorResponse: OCPP16Constants.OCPP_RESPONSE_EMPTY } )! } @@ -1369,7 +1370,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { return handleIncomingRequestError( chargingStation, OCPP16IncomingRequestCommand.RESERVE_NOW, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { errorResponse: OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED } )! } diff --git a/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts b/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts index 2bdbc697..ea0a3a1f 100644 --- a/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts +++ b/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts @@ -15,6 +15,7 @@ import { HashAlgorithmEnumType, InstallCertificateUseEnumType, } from '../../../types/ocpp/2.0/Common.js' +import { getErrorMessage } from '../../../utils/index.js' /** * Interface for ChargingStation with certificate manager @@ -421,7 +422,7 @@ export class OCPP20CertificateManager { } } catch (error) { return { - error: `Failed to store certificate: ${error instanceof Error ? error.message : String(error)}`, + error: `Failed to store certificate: ${getErrorMessage(error)}`, success: false, } } diff --git a/src/charging-station/ocpp/OCPPRequestService.ts b/src/charging-station/ocpp/OCPPRequestService.ts index 174b6a05..b9922d72 100644 --- a/src/charging-station/ocpp/OCPPRequestService.ts +++ b/src/charging-station/ocpp/OCPPRequestService.ts @@ -24,6 +24,7 @@ import { } from '../../types/index.js' import { clone, + ensureError, formatDurationMilliSeconds, handleSendMessageError, logger, @@ -116,7 +117,7 @@ export abstract class OCPPRequestService { chargingStation, commandName, MessageType.CALL_ERROR_MESSAGE, - error instanceof Error ? error : new Error(String(error)) + ensureError(error) ) return null } @@ -142,7 +143,7 @@ export abstract class OCPPRequestService { chargingStation, commandName, MessageType.CALL_RESULT_MESSAGE, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { throwError: true, } @@ -176,7 +177,7 @@ export abstract class OCPPRequestService { chargingStation, commandName, MessageType.CALL_MESSAGE, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), { throwError: params.throwError, } diff --git a/src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.ts b/src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.ts index c88ebd15..03553242 100644 --- a/src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.ts +++ b/src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.ts @@ -4,7 +4,7 @@ import type { OCPP20AuthAdapter } from '../adapters/OCPP20AuthAdapter.js' import { OCPPError } from '../../../../exception/OCPPError.js' import { ErrorType } from '../../../../types/index.js' import { OCPPVersion } from '../../../../types/ocpp/OCPPVersion.js' -import { logger } from '../../../../utils/index.js' +import { ensureError, getErrorMessage, logger } from '../../../../utils/index.js' import { type ChargingStation } from '../../../ChargingStation.js' import { AuthComponentFactory } from '../factories/AuthComponentFactory.js' import { @@ -144,13 +144,13 @@ export class OCPPAuthServiceImpl implements OCPPAuthService { timestamp: result.timestamp, } } catch (error) { - lastError = error instanceof Error ? error : new Error(String(error)) + lastError = ensureError(error) logger.debug( - `${this.chargingStation.logPrefix()} Strategy '${strategyName}' failed: ${error instanceof Error ? error.message : String(error)}` + `${this.chargingStation.logPrefix()} Strategy '${strategyName}' failed: ${getErrorMessage(error)}` ) // Continue to next strategy unless it's a critical error - if (this.isCriticalError(error instanceof Error ? error : new Error(String(error)))) { + if (this.isCriticalError(ensureError(error))) { break } } @@ -258,7 +258,7 @@ export class OCPPAuthServiceImpl implements OCPPAuthService { } catch (error) { const duration = Date.now() - startTime logger.error( - `${this.chargingStation.logPrefix()} Direct authentication with ${strategyName} failed (${String(duration)}ms): ${error instanceof Error ? error.message : String(error)}` + `${this.chargingStation.logPrefix()} Direct authentication with ${strategyName} failed (${String(duration)}ms): ${getErrorMessage(error)}` ) throw error } @@ -461,7 +461,7 @@ export class OCPPAuthServiceImpl implements OCPPAuthService { } } catch (error) { logger.debug( - `${this.chargingStation.logPrefix()} Local authorization check failed: ${error instanceof Error ? error.message : String(error)}` + `${this.chargingStation.logPrefix()} Local authorization check failed: ${getErrorMessage(error)}` ) } } diff --git a/src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.ts b/src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.ts index 415c2127..b151b8e5 100644 --- a/src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.ts +++ b/src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.ts @@ -5,7 +5,7 @@ import type { } from '../interfaces/OCPPAuthService.js' import type { AuthConfiguration, AuthorizationResult, AuthRequest } from '../types/AuthTypes.js' -import { logger } from '../../../../utils/index.js' +import { ensureError, getErrorMessage, logger } from '../../../../utils/index.js' import { AuthContext, AuthenticationError, @@ -106,13 +106,13 @@ export class LocalAuthStrategy implements AuthStrategy { ) return undefined } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Authentication error: ${errorMessage}`) throw new AuthenticationError( `Local authentication failed: ${errorMessage}`, AuthErrorCode.STRATEGY_ERROR, { - cause: error instanceof Error ? error : new Error(String(error)), + cause: ensureError(error), context: request.context, identifier: request.identifier.value, } @@ -137,7 +137,7 @@ export class LocalAuthStrategy implements AuthStrategy { this.authCache.set(identifier, result, ttl) logger.debug(`LocalAuthStrategy: Cached result for ${identifier}`) } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Failed to cache result: ${errorMessage}`) // Don't throw - caching is not critical } @@ -239,12 +239,12 @@ export class LocalAuthStrategy implements AuthStrategy { this.isInitialized = true logger.info('LocalAuthStrategy: Initialized successfully') } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Initialization failed: ${errorMessage}`) throw new AuthenticationError( `Local auth strategy initialization failed: ${errorMessage}`, AuthErrorCode.CONFIGURATION_ERROR, - { cause: error instanceof Error ? error : new Error(String(error)) } + { cause: ensureError(error) } ) } } @@ -262,7 +262,7 @@ export class LocalAuthStrategy implements AuthStrategy { this.authCache.remove(identifier) logger.debug(`LocalAuthStrategy: Invalidated cache for ${identifier}`) } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Failed to invalidate cache: ${errorMessage}`) // Don't throw - cache invalidation errors are not critical } @@ -282,7 +282,7 @@ export class LocalAuthStrategy implements AuthStrategy { const entry = await this.localAuthListManager.getEntry(identifier) return !!entry } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Error checking local list: ${errorMessage}`) return false } @@ -327,13 +327,13 @@ export class LocalAuthStrategy implements AuthStrategy { logger.debug(`LocalAuthStrategy: Cache hit for ${request.identifier.value}`) return cachedResult } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Cache check failed: ${errorMessage}`) throw new AuthenticationError( `Authorization cache check failed: ${errorMessage}`, AuthErrorCode.CACHE_ERROR, { - cause: error instanceof Error ? error : new Error(String(error)), + cause: ensureError(error), identifier: request.identifier.value, } ) @@ -385,13 +385,13 @@ export class LocalAuthStrategy implements AuthStrategy { timestamp: new Date(), } } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`LocalAuthStrategy: Local auth list check failed: ${errorMessage}`) throw new AuthenticationError( `Local auth list check failed: ${errorMessage}`, AuthErrorCode.LOCAL_LIST_ERROR, { - cause: error instanceof Error ? error : new Error(String(error)), + cause: ensureError(error), identifier: request.identifier.value, } ) diff --git a/src/charging-station/ocpp/auth/strategies/RemoteAuthStrategy.ts b/src/charging-station/ocpp/auth/strategies/RemoteAuthStrategy.ts index b0f917b8..b51c391e 100644 --- a/src/charging-station/ocpp/auth/strategies/RemoteAuthStrategy.ts +++ b/src/charging-station/ocpp/auth/strategies/RemoteAuthStrategy.ts @@ -7,7 +7,7 @@ import type { import type { AuthConfiguration, AuthorizationResult, AuthRequest } from '../types/AuthTypes.js' import { OCPPVersion } from '../../../../types/ocpp/OCPPVersion.js' -import { logger } from '../../../../utils/index.js' +import { ensureError, getErrorMessage, logger } from '../../../../utils/index.js' import { AuthenticationError, AuthenticationMethod, @@ -162,7 +162,7 @@ export class RemoteAuthStrategy implements AuthStrategy { this.stats.networkErrors++ } - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`RemoteAuthStrategy: Authentication error: ${errorMessage}`) // Don't rethrow - allow other strategies to handle @@ -274,7 +274,7 @@ export class RemoteAuthStrategy implements AuthStrategy { logger.debug(`RemoteAuthStrategy: OCPP ${version} adapter configured`) } } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error( `RemoteAuthStrategy: Configuration validation failed for OCPP ${version}: ${errorMessage}` ) @@ -288,12 +288,12 @@ export class RemoteAuthStrategy implements AuthStrategy { this.isInitialized = true logger.info('RemoteAuthStrategy: Initialized successfully') } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`RemoteAuthStrategy: Initialization failed: ${errorMessage}`) throw new AuthenticationError( `Remote auth strategy initialization failed: ${errorMessage}`, AuthErrorCode.CONFIGURATION_ERROR, - { cause: error instanceof Error ? error : new Error(String(error)) } + { cause: ensureError(error) } ) } } @@ -386,7 +386,7 @@ export class RemoteAuthStrategy implements AuthStrategy { `RemoteAuthStrategy: Cached result for ${identifier.substring(0, 8)}... (TTL: ${String(cacheTtl)}s)` ) } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.error(`RemoteAuthStrategy: Failed to cache result: ${errorMessage}`) // Don't throw - caching is not critical for authentication } @@ -418,7 +418,7 @@ export class RemoteAuthStrategy implements AuthStrategy { clearTimeout(timeoutHandle) return result } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) logger.debug(`RemoteAuthStrategy: Remote availability check failed: ${errorMessage}`) return false } @@ -501,12 +501,12 @@ export class RemoteAuthStrategy implements AuthStrategy { } // Wrap other errors as network errors - const errorMessage = error instanceof Error ? error.message : String(error) + const errorMessage = getErrorMessage(error) throw new AuthenticationError( `Remote authorization failed: ${errorMessage}`, AuthErrorCode.NETWORK_ERROR, { - cause: error instanceof Error ? error : new Error(String(error)), + cause: ensureError(error), context: request.context, identifier: request.identifier.value, } diff --git a/src/charging-station/ui-server/UIHttpServer.ts b/src/charging-station/ui-server/UIHttpServer.ts index 10b32a89..08268713 100644 --- a/src/charging-station/ui-server/UIHttpServer.ts +++ b/src/charging-station/ui-server/UIHttpServer.ts @@ -17,7 +17,7 @@ import { type UIServerConfiguration, type UUIDv4, } from '../../types/index.js' -import { generateUUID, JSONStringify, logger } from '../../utils/index.js' +import { generateUUID, getErrorMessage, JSONStringify, logger } from '../../utils/index.js' import { AbstractUIServer } from './AbstractUIServer.js' import { createBodySizeLimiter, @@ -202,7 +202,7 @@ export class UIHttpServer extends AbstractUIServer { } catch (error) { this.sendResponse( this.buildProtocolResponse(uuid, { - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, status: ResponseStatus.FAILURE, }) diff --git a/src/charging-station/ui-server/UIServerUtils.ts b/src/charging-station/ui-server/UIServerUtils.ts index 94894dde..dbed5ba1 100644 --- a/src/charging-station/ui-server/UIServerUtils.ts +++ b/src/charging-station/ui-server/UIServerUtils.ts @@ -2,7 +2,7 @@ import type { IncomingMessage } from 'node:http' import { BaseError } from '../../exception/index.js' import { Protocol, ProtocolVersion } from '../../types/index.js' -import { isEmpty, logger, logPrefix } from '../../utils/index.js' +import { getErrorMessage, isEmpty, logger, logPrefix } from '../../utils/index.js' export const getUsernameAndPasswordFromAuthorizationToken = ( authorizationToken: string, @@ -23,11 +23,7 @@ export const getUsernameAndPasswordFromAuthorizationToken = ( } return [username, password] } catch (error) { - next( - new BaseError( - `Invalid basic authentication token format: ${error instanceof Error ? error.message : String(error)}` - ) - ) + next(new BaseError(`Invalid basic authentication token format: ${getErrorMessage(error)}`)) return undefined } } diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index c7d9453b..6e753d4d 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -20,7 +20,14 @@ import { type StorageConfiguration, type UUIDv4, } from '../../../types/index.js' -import { Configuration, isAsyncFunction, isNotEmptyArray, logger } from '../../../utils/index.js' +import { + Configuration, + ensureError, + getErrorMessage, + isAsyncFunction, + isNotEmptyArray, + logger, +} from '../../../utils/index.js' import { Bootstrap } from '../../Bootstrap.js' import { UIServiceWorkerBroadcastChannel } from '../../broadcast-channel/UIServiceWorkerBroadcastChannel.js' import { DEFAULT_MAX_STATIONS, isValidNumberOfStations } from '../UIServerSecurity.js' @@ -163,7 +170,7 @@ export abstract class AbstractUIService { responsePayload = { command, errorDetails: error instanceof OCPPError ? error.details : undefined, - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, hashIds: requestPayload?.hashIds, requestPayload, @@ -274,7 +281,7 @@ export abstract class AbstractUIService { succeededStationInfos.push(stationInfo) } } catch (error) { - err = error instanceof Error ? error : new Error(String(error)) + err = ensureError(error) if (stationInfo != null) { failedStationInfos.push(stationInfo) } @@ -326,7 +333,7 @@ export abstract class AbstractUIService { } satisfies ResponsePayload } catch (error) { return { - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, status: ResponseStatus.FAILURE, } satisfies ResponsePayload @@ -341,7 +348,7 @@ export abstract class AbstractUIService { } satisfies ResponsePayload } catch (error) { return { - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, status: ResponseStatus.FAILURE, } satisfies ResponsePayload @@ -354,7 +361,7 @@ export abstract class AbstractUIService { return { status: ResponseStatus.SUCCESS } } catch (error) { return { - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, status: ResponseStatus.FAILURE, } satisfies ResponsePayload @@ -367,7 +374,7 @@ export abstract class AbstractUIService { return { status: ResponseStatus.SUCCESS } } catch (error) { return { - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: getErrorMessage(error), errorStack: error instanceof Error ? error.stack : undefined, status: ResponseStatus.FAILURE, } satisfies ResponsePayload diff --git a/src/performance/storage/JsonFileStorage.ts b/src/performance/storage/JsonFileStorage.ts index c5a9a571..3d1fa0d5 100644 --- a/src/performance/storage/JsonFileStorage.ts +++ b/src/performance/storage/JsonFileStorage.ts @@ -4,7 +4,13 @@ import { closeSync, openSync, writeSync } from 'node:fs' import { BaseError } from '../../exception/index.js' import { FileType, MapStringifyFormat, type Statistics } from '../../types/index.js' -import { AsyncLock, AsyncLockType, handleFileException, JSONStringify } from '../../utils/index.js' +import { + AsyncLock, + AsyncLockType, + ensureError, + handleFileException, + JSONStringify, +} from '../../utils/index.js' import { Storage } from './Storage.js' export class JsonFileStorage extends Storage { @@ -26,7 +32,7 @@ export class JsonFileStorage extends Storage { handleFileException( this.dbName, FileType.PerformanceRecords, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix ) } @@ -42,7 +48,7 @@ export class JsonFileStorage extends Storage { handleFileException( this.dbName, FileType.PerformanceRecords, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix ) } @@ -62,7 +68,7 @@ export class JsonFileStorage extends Storage { handleFileException( this.dbName, FileType.PerformanceRecords, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), this.logPrefix ) }) diff --git a/src/performance/storage/MikroOrmStorage.ts b/src/performance/storage/MikroOrmStorage.ts index a33b5faa..61bc54f5 100644 --- a/src/performance/storage/MikroOrmStorage.ts +++ b/src/performance/storage/MikroOrmStorage.ts @@ -5,7 +5,7 @@ import { type Options as MariaDbOptions, MikroORM as MariaDbORM } from '@mikro-o import { BaseError } from '../../exception/index.js' import { PerformanceRecord, type Statistics, StorageType } from '../../types/index.js' -import { Constants } from '../../utils/index.js' +import { Constants, ensureError } from '../../utils/index.js' import { Storage } from './Storage.js' export class MikroOrmStorage extends Storage { @@ -26,10 +26,7 @@ export class MikroOrmStorage extends Storage { delete this.orm } } catch (error) { - this.handleDBStorageError( - this.storageType, - error instanceof Error ? error : new Error(String(error)) - ) + this.handleDBStorageError(this.storageType, ensureError(error)) } } @@ -58,10 +55,7 @@ export class MikroOrmStorage extends Storage { } } } catch (error) { - this.handleDBStorageError( - this.storageType, - error instanceof Error ? error : new Error(String(error)) - ) + this.handleDBStorageError(this.storageType, ensureError(error)) } } @@ -77,7 +71,7 @@ export class MikroOrmStorage extends Storage { } catch (error) { this.handleDBStorageError( this.storageType, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), Constants.PERFORMANCE_RECORDS_TABLE ) } diff --git a/src/performance/storage/MongoDBStorage.ts b/src/performance/storage/MongoDBStorage.ts index 96764ab4..b00280aa 100644 --- a/src/performance/storage/MongoDBStorage.ts +++ b/src/performance/storage/MongoDBStorage.ts @@ -4,7 +4,7 @@ import { MongoClient } from 'mongodb' import { BaseError } from '../../exception/index.js' import { type Statistics, StorageType } from '../../types/index.js' -import { Constants } from '../../utils/index.js' +import { Constants, ensureError } from '../../utils/index.js' import { Storage } from './Storage.js' export class MongoDBStorage extends Storage { @@ -26,10 +26,7 @@ export class MongoDBStorage extends Storage { this.opened = false } } catch (error) { - this.handleDBStorageError( - StorageType.MONGO_DB, - error instanceof Error ? error : new Error(String(error)) - ) + this.handleDBStorageError(StorageType.MONGO_DB, ensureError(error)) } } @@ -40,10 +37,7 @@ export class MongoDBStorage extends Storage { this.opened = true } } catch (error) { - this.handleDBStorageError( - StorageType.MONGO_DB, - error instanceof Error ? error : new Error(String(error)) - ) + this.handleDBStorageError(StorageType.MONGO_DB, ensureError(error)) } } @@ -62,7 +56,7 @@ export class MongoDBStorage extends Storage { } catch (error) { this.handleDBStorageError( StorageType.MONGO_DB, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), Constants.PERFORMANCE_RECORDS_TABLE ) } diff --git a/src/utils/Configuration.ts b/src/utils/Configuration.ts index 5e10c8ef..2048d991 100644 --- a/src/utils/Configuration.ts +++ b/src/utils/Configuration.ts @@ -33,7 +33,7 @@ import { logPrefix, } from './ConfigurationUtils.js' import { Constants } from './Constants.js' -import { handleFileException } from './ErrorUtils.js' +import { ensureError, handleFileException } from './ErrorUtils.js' import { has, isCFEnvironment, mergeDeepRight, once } from './Utils.js' type ConfigurationSectionType = @@ -141,7 +141,7 @@ export class Configuration { handleFileException( Configuration.configurationFile, FileType.Configuration, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), logPrefix(), { consoleOut: true } ) @@ -560,7 +560,7 @@ export class Configuration { handleFileException( Configuration.configurationFile, FileType.Configuration, - error instanceof Error ? error : new Error(String(error)), + ensureError(error), logPrefix(), { consoleOut: true } ) diff --git a/src/utils/ErrorUtils.ts b/src/utils/ErrorUtils.ts index 5f4082c3..500e4d83 100644 --- a/src/utils/ErrorUtils.ts +++ b/src/utils/ErrorUtils.ts @@ -18,6 +18,12 @@ import { isNotEmptyString } from './Utils.js' const moduleName = 'ErrorUtils' +export const ensureError = (error: unknown): Error => + error instanceof Error ? error : new Error(String(error)) + +export const getErrorMessage = (error: unknown): string => + error instanceof Error ? error.message : String(error) + export const handleUncaughtException = (): void => { process.on('uncaughtException', (error: Error) => { console.error(chalk.red('Uncaught exception: '), error) diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts index 223b2d27..c8c84e92 100644 --- a/src/utils/FileUtils.ts +++ b/src/utils/FileUtils.ts @@ -2,7 +2,7 @@ import { type FSWatcher, watch, type WatchListener } from 'node:fs' import type { FileType } from '../types/index.js' -import { handleFileException } from './ErrorUtils.js' +import { ensureError, handleFileException } from './ErrorUtils.js' import { logger } from './Logger.js' import { isNotEmptyString } from './Utils.js' @@ -16,15 +16,9 @@ export const watchJsonFile = ( try { return watch(file, listener) } catch (error) { - handleFileException( - file, - fileType, - error instanceof Error ? error : new Error(String(error)), - logPrefix, - { - throwError: false, - } - ) + handleFileException(file, fileType, ensureError(error), logPrefix, { + throwError: false, + }) } } else { logger.info(`${logPrefix} No ${fileType} file to watch given. Not monitoring its changes`) diff --git a/src/utils/index.ts b/src/utils/index.ts index 456e98da..e708405b 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -9,6 +9,8 @@ export { Configuration } from './Configuration.js' export { Constants } from './Constants.js' export { ACElectricUtils, DCElectricUtils } from './ElectricUtils.js' export { + ensureError, + getErrorMessage, handleFileException, handleIncomingRequestError, handleSendMessageError, -- 2.53.0