Do not throw an error at OCPP message sending to avoid crashing the
authorJérôme Benoit <jerome.benoit@sap.com>
Thu, 24 Feb 2022 13:34:01 +0000 (14:34 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Thu, 24 Feb 2022 13:34:01 +0000 (14:34 +0100)
worker

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/performance/storage/Storage.ts
src/types/Error.ts [new file with mode: 0644]
src/utils/Configuration.ts
src/utils/FileUtils.ts

index 3fc960a9bef4dc27ebee284491b90e40110c8ff6..a56437f951e7a9999683584a0c4eaed6df7a230b 100644 (file)
@@ -1,4 +1,5 @@
 import type ChargingStation from '../ChargingStation';
+import { HandleErrorParams } from '../../types/Error';
 import { IncomingRequestCommand } from '../../types/ocpp/Requests';
 import { JsonType } from '../../types/JsonType';
 import logger from '../../utils/Logger';
@@ -18,12 +19,14 @@ export default abstract class OCPPIncomingRequestService {
     return OCPPIncomingRequestService.instances.get(chargingStation.id) as T;
   }
 
-  protected handleIncomingRequestError<T>(commandName: IncomingRequestCommand, error: Error, errorOcppResponse?: T): T {
+  protected handleIncomingRequestError<T>(commandName: IncomingRequestCommand, error: Error, errorOcppResponse?: T, params: HandleErrorParams = { throwError: true }): T {
     logger.error(this.chargingStation.logPrefix() + ' Incoming request command %s error: %j', commandName, error);
     if (errorOcppResponse) {
       return errorOcppResponse;
     }
-    throw error;
+    if (params?.throwError) {
+      throw error;
+    }
   }
 
   public abstract handleRequest(messageId: string, commandName: IncomingRequestCommand, commandPayload: JsonType): Promise<void>;
index 000d8c0a426816ab43a9f058baf1a4d56d629bae..db3ce5e02daf514d45ed1881fb33070e01f1c722 100644 (file)
@@ -7,6 +7,7 @@ import { ChargePointStatus } from '../../types/ocpp/ChargePointStatus';
 import type ChargingStation from '../ChargingStation';
 import Constants from '../../utils/Constants';
 import { ErrorType } from '../../types/ocpp/ErrorType';
+import { HandleErrorParams } from '../../types/Error';
 import { JsonType } from '../../types/JsonType';
 import { MessageType } from '../../types/ocpp/MessageType';
 import { MeterValue } from '../../types/ocpp/MeterValues';
@@ -58,7 +59,7 @@ export default abstract class OCPPRequestService {
     try {
       return await this.internalSendMessage(messageId, messagePayload, MessageType.CALL_MESSAGE, commandName, params);
     } catch (error) {
-      this.handleRequestError(commandName, error as Error);
+      this.handleRequestError(commandName, error as Error, { throwError: false });
     }
   }
 
@@ -173,9 +174,11 @@ export default abstract class OCPPRequestService {
     return messageToSend;
   }
 
-  private handleRequestError(commandName: RequestCommand | IncomingRequestCommand, error: Error): void {
+  private handleRequestError(commandName: RequestCommand | IncomingRequestCommand, error: Error, params: HandleErrorParams = { throwError: true }): void {
     logger.error(this.chargingStation.logPrefix() + ' Request command %s error: %j', commandName, error);
-    throw error;
+    if (params?.throwError) {
+      throw error;
+    }
   }
 
   public abstract sendHeartbeat(params?: SendParams): Promise<void>;
index db33a694777e5efe0e415bf96c2874b7ad434cba..2f5feccee9a2e2b888e1a9bfef353ab4ff7d002d 100644 (file)
@@ -2,6 +2,7 @@
 
 import { DBName, StorageType } from '../../types/Storage';
 
+import { HandleErrorParams } from '../../types/Error';
 import Statistics from '../../types/Statistics';
 import { URL } from 'url';
 import Utils from '../../utils/Utils';
@@ -17,8 +18,11 @@ export abstract class Storage {
     this.logPrefix = logPrefix;
   }
 
-  protected handleDBError(type: StorageType, error: Error, table?: string): void {
+  protected handleDBError(type: StorageType, error: Error, table?: string, params: HandleErrorParams = { throwError: false }): void {
     logger.error(`${this.logPrefix} ${this.getDBNameFromStorageType(type)} error '${error.message}'${(!Utils.isNullOrUndefined(table) || !table) && ` in table or collection '${table}'`}: %j`, error);
+    if (params?.throwError) {
+      throw error;
+    }
   }
 
   protected getDBNameFromStorageType(type: StorageType): DBName {
diff --git a/src/types/Error.ts b/src/types/Error.ts
new file mode 100644 (file)
index 0000000..c599438
--- /dev/null
@@ -0,0 +1,4 @@
+export interface HandleErrorParams {
+  throwError?: boolean;
+  consoleOut?: boolean;
+}
index 519f0465b1580f2bbb4f781777d0ff080849a0e2..d88526a23648da293f0c6556c731c80b050b99b4 100644 (file)
@@ -1,6 +1,7 @@
 import ConfigurationData, { StationTemplateUrl, StorageConfiguration, SupervisionUrlDistribution, UIWebSocketServerConfiguration } from '../types/ConfigurationData';
 
 import Constants from './Constants';
+import { HandleErrorParams } from '../types/Error';
 import { ServerOptions } from 'ws';
 import { StorageType } from '../types/Storage';
 import type { WorkerChoiceStrategy } from 'poolifier';
@@ -228,7 +229,7 @@ export default class Configuration {
     return typeof obj === 'undefined';
   }
 
-  private static handleFileException(logPrefix: string, fileType: string, filePath: string, error: NodeJS.ErrnoException): void {
+  private static handleFileException(logPrefix: string, fileType: string, filePath: string, error: NodeJS.ErrnoException, params: HandleErrorParams = { throwError: true }): void {
     const prefix = logPrefix.length !== 0 ? logPrefix + ' ' : '';
     if (error.code === 'ENOENT') {
       console.error(chalk.green(prefix) + chalk.red(fileType + ' file ' + filePath + ' not found: '), error);
@@ -239,6 +240,8 @@ export default class Configuration {
     } else {
       console.error(chalk.green(prefix) + chalk.red(fileType + ' file ' + filePath + ' error: '), error);
     }
-    throw error;
+    if (params?.throwError) {
+      throw error;
+    }
   }
 }
index e68500e33b5821a2dc5d9f5876949b7d3ac28d9f..a0d495a6b79104c92fbfd7fae2030fb365288064 100644 (file)
@@ -1,34 +1,38 @@
+import { HandleErrorParams } from '../types/Error';
 import chalk from 'chalk';
 import logger from './Logger';
 
 export default class FileUtils {
-  static handleFileException(logPrefix: string, fileType: string, filePath: string, error: NodeJS.ErrnoException, consoleOut = false): void {
+  static handleFileException(logPrefix: string, fileType: string, filePath: string, error: NodeJS.ErrnoException,
+      params: HandleErrorParams = { throwError: true, consoleOut: false }): void {
     const prefix = logPrefix.length !== 0 ? logPrefix + ' ' : '';
     if (error.code === 'ENOENT') {
-      if (consoleOut) {
+      if (params?.consoleOut) {
         console.warn(chalk.green(prefix) + chalk.yellow(fileType + ' file ' + filePath + ' not found: '), error);
       } else {
         logger.warn(prefix + fileType + ' file ' + filePath + ' not found: %j', error);
       }
     } else if (error.code === 'EEXIST') {
-      if (consoleOut) {
+      if (params?.consoleOut) {
         console.warn(chalk.green(prefix) + chalk.yellow(fileType + ' file ' + filePath + ' already exists: '), error);
       } else {
         logger.warn(prefix + fileType + ' file ' + filePath + ' already exists: %j', error);
       }
     } else if (error.code === 'EACCES') {
-      if (consoleOut) {
+      if (params?.consoleOut) {
         console.warn(chalk.green(prefix) + chalk.yellow(fileType + ' file ' + filePath + ' access denied: '), error);
       } else {
         logger.warn(prefix + fileType + ' file ' + filePath + ' access denied: %j', error);
       }
     } else {
-      if (consoleOut) {
+      if (params?.consoleOut) {
         console.warn(chalk.green(prefix) + chalk.yellow(fileType + ' file ' + filePath + ' error: '), error);
       } else {
         logger.warn(prefix + fileType + ' file ' + filePath + ' error: %j', error);
       }
-      throw error;
+      if (params?.throwError) {
+        throw error;
+      }
     }
   }
 }