]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
refactor: extract ensureError and getErrorMessage helpers
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 16 Mar 2026 15:33:41 +0000 (16:33 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Mon, 16 Mar 2026 15:33:41 +0000 (16:33 +0100)
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.

20 files changed:
src/charging-station/ChargingStation.ts
src/charging-station/ChargingStationWorker.ts
src/charging-station/IdTagsCache.ts
src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.ts
src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.ts
src/charging-station/ocpp/auth/strategies/RemoteAuthStrategy.ts
src/charging-station/ui-server/UIHttpServer.ts
src/charging-station/ui-server/UIServerUtils.ts
src/charging-station/ui-server/ui-services/AbstractUIService.ts
src/performance/storage/JsonFileStorage.ts
src/performance/storage/MikroOrmStorage.ts
src/performance/storage/MongoDBStorage.ts
src/utils/Configuration.ts
src/utils/ErrorUtils.ts
src/utils/FileUtils.ts
src/utils/index.ts

index 38962392e013997e833fca1b83d72ea74dac1912..a70705daa777b14750028fce18429ae6a2fe3bcb 100644 (file)
@@ -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()
         )
       }
index 58f63ff9d50f20f711f1118feb34db09e80e32fd..37d0406aef8e38be9a6c5e2ba345a985de0c2980 100644 (file)
@@ -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,
                 },
index dde5d8d1a4b748dc5f22a7237adf5e235936cdd8..8e982e0d56b33329089bbff707fae33e0e4738ec 100644 (file)
@@ -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,
index 3b173a76fd971100873289987a6dff3883ae8537..ba414170d30f9e106b74406945ebdccd1be12d00 100644 (file)
@@ -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,
index a530bc2780da772c26bfab0e3c1fbc6d82678585..54b8c95ded13dc340a63a47013c7dfcdeb6660aa 100644 (file)
@@ -106,6 +106,7 @@ import {
   Configuration,
   convertToDate,
   convertToInt,
+  ensureError,
   formatDurationMilliSeconds,
   handleIncomingRequestError,
   isEmpty,
@@ -657,7 +658,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return handleIncomingRequestError<GenericResponse>(
         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<OCPP16DataTransferResponse>(
         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<GetDiagnosticsResponse>(
           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<OCPP16ReserveNowResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
-        error instanceof Error ? error : new Error(String(error)),
+        ensureError(error),
         { errorResponse: OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED }
       )!
     }
index 2bdbc69776212f400d00fbcfefdb1f23e7662071..ea0a3a1f35af84f7af54c6452ee0803cd751f351 100644 (file)
@@ -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,
       }
     }
index 174b6a05023e85e6eebc68ba45fcd6d189ce7534..b9922d7260588733544764eac453ecb6196e3532 100644 (file)
@@ -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,
         }
index c88ebd153c0c110a1c3fef0a2181493de55935e5..03553242f45c80553f546c974aedd481f32d862b 100644 (file)
@@ -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)}`
         )
       }
     }
index 415c21277c3777b063d1e135a903aa9bb8c5d912..b151b8e5c309fa40e8afe81a7f5c1856118ab93b 100644 (file)
@@ -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,
         }
       )
index b0f917b8e21de466b0d819ae5dedaf2cb1de5a3e..b51c391e4a9b0d39a5ede786e07277701a0b2cfd 100644 (file)
@@ -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,
         }
index 10b32a89c1d54f81fa79d8a734dbd1225541d49b..08268713aef32ec05a297d7638ac7f513422e956 100644 (file)
@@ -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,
                 })
index 94894dde30809589d9594f5dba795f86701146e0..dbed5ba1b0f883ac700d219499747aa06040be44 100644 (file)
@@ -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
   }
 }
index c7d9453b13b95a7378ea57bd69efb32030975993..6e753d4d199cf8c811421cee6bfe0f43c4636b8b 100644 (file)
@@ -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
index c5a9a571318a1b0fadcda47549d4d796706db34e..3d1fa0d56d271e97f78480e5f6835034d2dab739 100644 (file)
@@ -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
       )
     })
index a33b5faae741ee5f4b5a738d1a57e1799c1bed55..61bc54f50dd1012a1cee6faee3c23815ab3368cc 100644 (file)
@@ -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
       )
     }
index 96764ab477d988fe8b6e3d141183d700c266dc45..b00280aa3780c171629e2708c5ce271a13b5cf75 100644 (file)
@@ -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
       )
     }
index 5e10c8efcedd22e4d070888044a2377c66c527a4..2048d9914cf13cc040fbcd5e60af34cbbe4fe295 100644 (file)
@@ -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 }
       )
index 5f4082c3c76e1d4d2db23d00abc092c6b27ac98f..500e4d836225d0207467e73a75a2e8e233ae9fe2 100644 (file)
@@ -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)
index 223b2d27260cb9cce4065a65afd7b7718adb0bbf..c8c84e9276d3b60a0b8dc85de95405e3f43ca469 100644 (file)
@@ -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`)
index 456e98da0cd57bae2abe1d7610c15338640fdc2a..e708405bb5cdfc72cd37e5f46b15bc21d7e0fc65 100644 (file)
@@ -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,