]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
refactor: replace 54 unsafe error casts with instanceof guards
authorJérôme Benoit <jerome.benoit@sap.com>
Sun, 15 Mar 2026 23:13:20 +0000 (00:13 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sun, 15 Mar 2026 23:13:20 +0000 (00:13 +0100)
All 'error as Error', 'error as OCPPError', and 'error as
NodeJS.ErrnoException' casts replaced with proper instanceof
type narrowing across 16 files. Uses the pattern already
established in the auth strategies module:
  error instanceof Error ? error.message : String(error)

For call sites that pass error objects to functions, wraps
non-Error values: error instanceof Error ? error : new Error(String(error))

16 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/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/FileUtils.ts

index 7e6585276af4e0dfba7ce0bf7211a9339fd957ab..38962392e013997e833fca1b83d72ea74dac1912 100644 (file)
@@ -1356,7 +1356,7 @@ export class ChargingStation extends EventEmitter {
         handleFileException(
           this.configurationFile,
           FileType.ChargingStationConfiguration,
-          error as NodeJS.ErrnoException,
+          error instanceof Error ? error : new Error(String(error)),
           this.logPrefix()
         )
         if (
@@ -1628,7 +1628,7 @@ export class ChargingStation extends EventEmitter {
       handleFileException(
         this.templateFile,
         FileType.ChargingStationTemplate,
-        error as NodeJS.ErrnoException,
+        error instanceof Error ? error : new Error(String(error)),
         this.logPrefix()
       )
     }
@@ -2211,6 +2211,13 @@ export class ChargingStation extends EventEmitter {
       let requestCommandName: IncomingRequestCommand | RequestCommand | undefined
       let errorCallback: ErrorCallback
       const [, messageId] = request
+      const ocppError =
+        error instanceof OCPPError
+          ? error
+          : new OCPPError(
+            ErrorType.INTERNAL_ERROR,
+            error instanceof Error ? error.message : String(error)
+          )
       switch (messageType) {
         case MessageType.CALL_ERROR_MESSAGE:
         case MessageType.CALL_RESULT_MESSAGE:
@@ -2218,7 +2225,7 @@ export class ChargingStation extends EventEmitter {
             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             ;[, errorCallback, requestCommandName] = this.getCachedRequest(messageType, messageId)!
             // Reject the deferred promise in case of error at response handling (rejecting an already fulfilled promise is a no-op)
-            errorCallback(error as OCPPError, false)
+            errorCallback(ocppError, false)
           } else {
             // Remove the request from the cache in case of error at response handling
             this.requests.delete(messageId)
@@ -2227,7 +2234,7 @@ export class ChargingStation extends EventEmitter {
         case MessageType.CALL_MESSAGE:
           ;[, , commandName] = request as IncomingRequest
           // Send error
-          await this.ocppRequestService.sendError(this, messageId, error as OCPPError, commandName)
+          await this.ocppRequestService.sendError(this, messageId, ocppError, commandName)
           break
       }
       if (!(error instanceof OCPPError)) {
@@ -2444,7 +2451,7 @@ export class ChargingStation extends EventEmitter {
             handleFileException(
               this.configurationFile,
               FileType.ChargingStationConfiguration,
-              error as NodeJS.ErrnoException,
+              error instanceof Error ? error : new Error(String(error)),
               this.logPrefix()
             )
           })
@@ -2459,7 +2466,7 @@ export class ChargingStation extends EventEmitter {
         handleFileException(
           this.configurationFile,
           FileType.ChargingStationConfiguration,
-          error as NodeJS.ErrnoException,
+          error instanceof Error ? error : new Error(String(error)),
           this.logPrefix()
         )
       }
index f850a3cd7d0a9921919f51b8c454edce26d9309a..58f63ff9d50f20f711f1118feb34db09e80e32fd 100644 (file)
@@ -64,9 +64,9 @@ if (Configuration.workerPoolInUse()) {
               parentPort?.postMessage({
                 data: {
                   event,
-                  message: (error as Error).message,
-                  name: (error as Error).name,
-                  stack: (error as Error).stack,
+                  message: error instanceof Error ? error.message : String(error),
+                  name: error instanceof Error ? error.name : 'UnknownError',
+                  stack: error instanceof Error ? error.stack : undefined,
                 },
                 event: WorkerMessageEvents.workerElementError,
                 uuid,
index 6aed7fb615f24e1212363307690f5cf757e15518..dde5d8d1a4b748dc5f22a7237adf5e235936cdd8 100644 (file)
@@ -128,7 +128,7 @@ export class IdTagsCache {
         handleFileException(
           file,
           FileType.Authorization,
-          error as NodeJS.ErrnoException,
+          error instanceof Error ? error : new Error(String(error)),
           this.logPrefix(file)
         )
       }
@@ -187,7 +187,7 @@ export class IdTagsCache {
               handleFileException(
                 file,
                 FileType.Authorization,
-                error as NodeJS.ErrnoException,
+                error instanceof Error ? error : new Error(String(error)),
                 this.logPrefix(file),
                 {
                   throwError: false,
index b5a728b5805412103c81d18c8ee43ab52a2b1824..de73e686ceef127c05e9ef62616da61ef444c635 100644 (file)
@@ -2,7 +2,7 @@ import { secondsToMilliseconds } from 'date-fns'
 
 import type { ChargingStation } from '../ChargingStation.js'
 
-import { BaseError, type OCPPError } from '../../exception/index.js'
+import { BaseError, OCPPError } from '../../exception/index.js'
 import {
   AuthorizationStatus,
   type AuthorizeRequest,
@@ -679,9 +679,9 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne
         )
         responsePayload = {
           command,
-          errorDetails: (error as OCPPError).details,
-          errorMessage: (error as OCPPError).message,
-          errorStack: (error as OCPPError).stack,
+          errorDetails: error instanceof OCPPError ? error.details : undefined,
+          errorMessage: error instanceof Error ? error.message : String(error),
+          errorStack: error instanceof Error ? error.stack : undefined,
           hashId: this.chargingStation.stationInfo?.hashId,
           requestPayload,
           status: ResponseStatus.FAILURE,
index 55264ac1a67676878cddc01731ef33de78981c36..b9c0bdaaebe59f908dddd29ae65fd333b9ae2273 100644 (file)
@@ -645,7 +645,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return handleIncomingRequestError<GenericResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         {
           errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED,
         }
@@ -906,7 +906,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return handleIncomingRequestError<OCPP16DataTransferResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.DATA_TRANSFER,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         { errorResponse: OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_REJECTED }
       )!
     }
@@ -1150,7 +1150,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         return handleIncomingRequestError<GetDiagnosticsResponse>(
           chargingStation,
           OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
-          error as Error,
+          error instanceof Error ? error : new Error(String(error)),
           { errorResponse: OCPP16Constants.OCPP_RESPONSE_EMPTY }
         )!
       }
@@ -1357,7 +1357,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return handleIncomingRequestError<OCPP16ReserveNowResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         { errorResponse: OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED }
       )!
     }
index c44fb2d8c915bce9cb75b146afe6c16201eb2137..2bdbc69776212f400d00fbcfefdb1f23e7662071 100644 (file)
@@ -421,7 +421,7 @@ export class OCPP20CertificateManager {
       }
     } catch (error) {
       return {
-        error: `Failed to store certificate: ${(error as Error).message}`,
+        error: `Failed to store certificate: ${error instanceof Error ? error.message : String(error)}`,
         success: false,
       }
     }
index 19942fab48a17aa8c6085067254a2b3de4959c7e..b9e09b18950719d240ce621384b20bba7c3271c2 100644 (file)
@@ -116,7 +116,7 @@ export abstract class OCPPRequestService {
         chargingStation,
         commandName,
         MessageType.CALL_ERROR_MESSAGE,
-        error as Error
+        error instanceof Error ? error : new Error(String(error))
       )
       return null
     }
@@ -142,7 +142,7 @@ export abstract class OCPPRequestService {
         chargingStation,
         commandName,
         MessageType.CALL_RESULT_MESSAGE,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         {
           throwError: true,
         }
@@ -176,7 +176,7 @@ export abstract class OCPPRequestService {
         chargingStation,
         commandName,
         MessageType.CALL_MESSAGE,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         {
           throwError: params.throwError,
         }
index 3a926e3452986fe59821c7db6b6ff0bd2a39d997..c88ebd153c0c110a1c3fef0a2181493de55935e5 100644 (file)
@@ -144,13 +144,13 @@ export class OCPPAuthServiceImpl implements OCPPAuthService {
           timestamp: result.timestamp,
         }
       } catch (error) {
-        lastError = error as Error
+        lastError = error instanceof Error ? error : new Error(String(error))
         logger.debug(
-          `${this.chargingStation.logPrefix()} Strategy '${strategyName}' failed: ${(error as Error).message}`
+          `${this.chargingStation.logPrefix()} Strategy '${strategyName}' failed: ${error instanceof Error ? error.message : String(error)}`
         )
 
         // Continue to next strategy unless it's a critical error
-        if (this.isCriticalError(error as Error)) {
+        if (this.isCriticalError(error instanceof Error ? error : new Error(String(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 as Error).message}`
+        `${this.chargingStation.logPrefix()} Direct authentication with ${strategyName} failed (${String(duration)}ms): ${error instanceof Error ? error.message : String(error)}`
       )
       throw error
     }
@@ -461,7 +461,7 @@ export class OCPPAuthServiceImpl implements OCPPAuthService {
         }
       } catch (error) {
         logger.debug(
-          `${this.chargingStation.logPrefix()} Local authorization check failed: ${(error as Error).message}`
+          `${this.chargingStation.logPrefix()} Local authorization check failed: ${error instanceof Error ? error.message : String(error)}`
         )
       }
     }
index cf6fee380bf48bf3e8578e9b03a6b7608cc3f298..10b32a89c1d54f81fa79d8a734dbd1225541d49b 100644 (file)
@@ -202,8 +202,8 @@ export class UIHttpServer extends AbstractUIServer {
             } catch (error) {
               this.sendResponse(
                 this.buildProtocolResponse(uuid, {
-                  errorMessage: (error as Error).message,
-                  errorStack: (error as Error).stack,
+                  errorMessage: error instanceof Error ? error.message : String(error),
+                  errorStack: error instanceof Error ? error.stack : undefined,
                   status: ResponseStatus.FAILURE,
                 })
               )
index 50ed36f3b126153f1f8b08379c54dc7576ff501f..94894dde30809589d9594f5dba795f86701146e0 100644 (file)
@@ -23,7 +23,11 @@ export const getUsernameAndPasswordFromAuthorizationToken = (
     }
     return [username, password]
   } catch (error) {
-    next(new BaseError(`Invalid basic authentication token format: ${(error as Error).message}`))
+    next(
+      new BaseError(
+        `Invalid basic authentication token format: ${error instanceof Error ? error.message : String(error)}`
+      )
+    )
     return undefined
   }
 }
index 98b0e1a7383f7295515bc4ba31efc8fa1455d791..c7d9453b13b95a7378ea57bd69efb32030975993 100644 (file)
@@ -1,6 +1,6 @@
 import type { AbstractUIServer } from '../AbstractUIServer.js'
 
-import { BaseError, type OCPPError } from '../../../exception/index.js'
+import { BaseError, OCPPError } from '../../../exception/index.js'
 import {
   BroadcastChannelProcedureName,
   type BroadcastChannelRequestPayload,
@@ -162,9 +162,9 @@ export abstract class AbstractUIService {
       logger.error(`${this.logPrefix(moduleName, 'requestHandler')} Handle request error:`, error)
       responsePayload = {
         command,
-        errorDetails: (error as OCPPError).details,
-        errorMessage: (error as OCPPError).message,
-        errorStack: (error as OCPPError).stack,
+        errorDetails: error instanceof OCPPError ? error.details : undefined,
+        errorMessage: error instanceof Error ? error.message : String(error),
+        errorStack: error instanceof Error ? error.stack : undefined,
         hashIds: requestPayload?.hashIds,
         requestPayload,
         responsePayload,
@@ -274,7 +274,7 @@ export abstract class AbstractUIService {
           succeededStationInfos.push(stationInfo)
         }
       } catch (error) {
-        err = error as Error
+        err = error instanceof Error ? error : new Error(String(error))
         if (stationInfo != null) {
           failedStationInfos.push(stationInfo)
         }
@@ -326,8 +326,8 @@ export abstract class AbstractUIService {
       } satisfies ResponsePayload
     } catch (error) {
       return {
-        errorMessage: (error as Error).message,
-        errorStack: (error as Error).stack,
+        errorMessage: error instanceof Error ? error.message : String(error),
+        errorStack: error instanceof Error ? error.stack : undefined,
         status: ResponseStatus.FAILURE,
       } satisfies ResponsePayload
     }
@@ -341,8 +341,8 @@ export abstract class AbstractUIService {
       } satisfies ResponsePayload
     } catch (error) {
       return {
-        errorMessage: (error as Error).message,
-        errorStack: (error as Error).stack,
+        errorMessage: error instanceof Error ? error.message : String(error),
+        errorStack: error instanceof Error ? error.stack : undefined,
         status: ResponseStatus.FAILURE,
       } satisfies ResponsePayload
     }
@@ -354,8 +354,8 @@ export abstract class AbstractUIService {
       return { status: ResponseStatus.SUCCESS }
     } catch (error) {
       return {
-        errorMessage: (error as Error).message,
-        errorStack: (error as Error).stack,
+        errorMessage: error instanceof Error ? error.message : String(error),
+        errorStack: error instanceof Error ? error.stack : undefined,
         status: ResponseStatus.FAILURE,
       } satisfies ResponsePayload
     }
@@ -367,8 +367,8 @@ export abstract class AbstractUIService {
       return { status: ResponseStatus.SUCCESS }
     } catch (error) {
       return {
-        errorMessage: (error as Error).message,
-        errorStack: (error as Error).stack,
+        errorMessage: error instanceof Error ? error.message : String(error),
+        errorStack: error instanceof Error ? error.stack : undefined,
         status: ResponseStatus.FAILURE,
       } satisfies ResponsePayload
     }
index ee145879ec3dd6d69c25faaea49abf9903d0319a..c5a9a571318a1b0fadcda47549d4d796706db34e 100644 (file)
@@ -26,7 +26,7 @@ export class JsonFileStorage extends Storage {
       handleFileException(
         this.dbName,
         FileType.PerformanceRecords,
-        error as NodeJS.ErrnoException,
+        error instanceof Error ? error : new Error(String(error)),
         this.logPrefix
       )
     }
@@ -42,7 +42,7 @@ export class JsonFileStorage extends Storage {
       handleFileException(
         this.dbName,
         FileType.PerformanceRecords,
-        error as NodeJS.ErrnoException,
+        error instanceof Error ? error : new Error(String(error)),
         this.logPrefix
       )
     }
@@ -62,7 +62,7 @@ export class JsonFileStorage extends Storage {
       handleFileException(
         this.dbName,
         FileType.PerformanceRecords,
-        error as NodeJS.ErrnoException,
+        error instanceof Error ? error : new Error(String(error)),
         this.logPrefix
       )
     })
index 42da83d3328eacfadcbf1a57a055d3abd3dcf038..a33b5faae741ee5f4b5a738d1a57e1799c1bed55 100644 (file)
@@ -26,7 +26,10 @@ export class MikroOrmStorage extends Storage {
         delete this.orm
       }
     } catch (error) {
-      this.handleDBStorageError(this.storageType, error as Error)
+      this.handleDBStorageError(
+        this.storageType,
+        error instanceof Error ? error : new Error(String(error))
+      )
     }
   }
 
@@ -55,7 +58,10 @@ export class MikroOrmStorage extends Storage {
         }
       }
     } catch (error) {
-      this.handleDBStorageError(this.storageType, error as Error)
+      this.handleDBStorageError(
+        this.storageType,
+        error instanceof Error ? error : new Error(String(error))
+      )
     }
   }
 
@@ -71,7 +77,7 @@ export class MikroOrmStorage extends Storage {
     } catch (error) {
       this.handleDBStorageError(
         this.storageType,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         Constants.PERFORMANCE_RECORDS_TABLE
       )
     }
index 0dc033d239873810403645804431d57110625201..96764ab477d988fe8b6e3d141183d700c266dc45 100644 (file)
@@ -26,7 +26,10 @@ export class MongoDBStorage extends Storage {
         this.opened = false
       }
     } catch (error) {
-      this.handleDBStorageError(StorageType.MONGO_DB, error as Error)
+      this.handleDBStorageError(
+        StorageType.MONGO_DB,
+        error instanceof Error ? error : new Error(String(error))
+      )
     }
   }
 
@@ -37,7 +40,10 @@ export class MongoDBStorage extends Storage {
         this.opened = true
       }
     } catch (error) {
-      this.handleDBStorageError(StorageType.MONGO_DB, error as Error)
+      this.handleDBStorageError(
+        StorageType.MONGO_DB,
+        error instanceof Error ? error : new Error(String(error))
+      )
     }
   }
 
@@ -56,7 +62,7 @@ export class MongoDBStorage extends Storage {
     } catch (error) {
       this.handleDBStorageError(
         StorageType.MONGO_DB,
-        error as Error,
+        error instanceof Error ? error : new Error(String(error)),
         Constants.PERFORMANCE_RECORDS_TABLE
       )
     }
index b4eb5538a18a59a3e77707f736b78f551c8ec3d6..5e10c8efcedd22e4d070888044a2377c66c527a4 100644 (file)
@@ -141,7 +141,7 @@ export class Configuration {
         handleFileException(
           Configuration.configurationFile,
           FileType.Configuration,
-          error as NodeJS.ErrnoException,
+          error instanceof Error ? error : new Error(String(error)),
           logPrefix(),
           { consoleOut: true }
         )
@@ -560,7 +560,7 @@ export class Configuration {
       handleFileException(
         Configuration.configurationFile,
         FileType.Configuration,
-        error as NodeJS.ErrnoException,
+        error instanceof Error ? error : new Error(String(error)),
         logPrefix(),
         { consoleOut: true }
       )
index 769f5da71489a443a26c010b6b2a47a9c8ca8b5f..223b2d27260cb9cce4065a65afd7b7718adb0bbf 100644 (file)
@@ -16,9 +16,15 @@ export const watchJsonFile = (
     try {
       return watch(file, listener)
     } catch (error) {
-      handleFileException(file, fileType, error as NodeJS.ErrnoException, logPrefix, {
-        throwError: false,
-      })
+      handleFileException(
+        file,
+        fileType,
+        error instanceof Error ? error : new Error(String(error)),
+        logPrefix,
+        {
+          throwError: false,
+        }
+      )
     }
   } else {
     logger.info(`${logPrefix} No ${fileType} file to watch given. Not monitoring its changes`)