Refine and use OCPP error specialisation
authorJérôme Benoit <jerome.benoit@sap.com>
Sun, 29 Aug 2021 16:01:06 +0000 (18:01 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sun, 29 Aug 2021 16:01:06 +0000 (18:01 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ChargingStation.ts
src/charging-station/OCPPError.ts [deleted file]
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16RequestService.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts
src/charging-station/ocpp/OCPPError.ts [new file with mode: 0644]
src/charging-station/ocpp/OCPPRequestService.ts
src/types/ocpp/Requests.ts

index ebb53a9feef722fbc79e7aa4be5e5dbded75639d..1626a9b3e74fa286d0ce68cb8f2d7e43425f35a7 100644 (file)
@@ -14,12 +14,13 @@ import ChargingStationInfo from '../types/ChargingStationInfo';
 import { ClientRequestArgs } from 'http';
 import Configuration from '../utils/Configuration';
 import Constants from '../utils/Constants';
+import { ErrorType } from '../types/ocpp/ErrorType';
 import FileUtils from '../utils/FileUtils';
 import { MessageType } from '../types/ocpp/MessageType';
 import OCPP16IncomingRequestService from './ocpp/1.6/OCPP16IncomingRequestService';
 import OCPP16RequestService from './ocpp/1.6/OCPP16RequestService';
 import OCPP16ResponseService from './ocpp/1.6/OCPP16ResponseService';
-import OCPPError from './OCPPError';
+import OCPPError from './ocpp/OCPPError';
 import OCPPIncomingRequestService from './ocpp/OCPPIncomingRequestService';
 import OCPPRequestService from './ocpp/OCPPRequestService';
 import { OCPPVersion } from '../types/ocpp/OCPPVersion';
@@ -649,7 +650,7 @@ export default class ChargingStation {
         // Parse the message
         [messageType, messageId, commandName, commandPayload, errorDetails] = request;
       } else {
-        throw new Error('Incoming request is not iterable');
+        throw new OCPPError(ErrorType.PROTOCOL_ERROR, 'Incoming request is not iterable');
       }
       // Check the Type of message
       switch (messageType) {
@@ -667,11 +668,11 @@ export default class ChargingStation {
           if (Utils.isIterable(this.requests[messageId])) {
             [responseCallback, , requestPayload] = this.requests[messageId];
           } else {
-            throw new Error(`Response request for message id ${messageId} is not iterable`);
+            throw new OCPPError(ErrorType.PROTOCOL_ERROR, `Response request for message id ${messageId} is not iterable`);
           }
           if (!responseCallback) {
             // Error
-            throw new Error(`Response request for unknown message id ${messageId}`);
+            throw new OCPPError(ErrorType.INTERNAL_ERROR, `Response request for unknown message id ${messageId}`);
           }
           delete this.requests[messageId];
           responseCallback(commandName, requestPayload);
@@ -680,12 +681,12 @@ export default class ChargingStation {
         case MessageType.CALL_ERROR_MESSAGE:
           if (!this.requests[messageId]) {
             // Error
-            throw new Error(`Error request for unknown message id ${messageId}`);
+            throw new OCPPError(ErrorType.INTERNAL_ERROR, `Error request for unknown message id ${messageId}`);
           }
           if (Utils.isIterable(this.requests[messageId])) {
             [, rejectCallback] = this.requests[messageId];
           } else {
-            throw new Error(`Error request for message id ${messageId} is not iterable`);
+            throw new OCPPError(ErrorType.PROTOCOL_ERROR, `Error request for message id ${messageId} is not iterable`);
           }
           delete this.requests[messageId];
           rejectCallback(new OCPPError(commandName, commandPayload.toString(), errorDetails));
@@ -694,7 +695,7 @@ export default class ChargingStation {
         default:
           errMsg = `${this.logPrefix()} Wrong message type ${messageType}`;
           logger.error(errMsg);
-          throw new Error(errMsg);
+          throw new OCPPError(ErrorType.PROTOCOL_ERROR, errMsg);
       }
     } catch (error) {
       // Log
diff --git a/src/charging-station/OCPPError.ts b/src/charging-station/OCPPError.ts
deleted file mode 100644 (file)
index 6780b60..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ErrorType } from '../types/ocpp/ErrorType';
-
-export default class OCPPError extends Error {
-  code: string;
-  details?: any;
-
-  constructor(code: string, message: string, details?: any) {
-    super(message);
-
-    this.code = code ?? ErrorType.GENERIC_ERROR;
-    this.message = message ?? '';
-    this.details = details ?? {};
-
-    Object.setPrototypeOf(this, OCPPError.prototype); // For instanceof
-
-    Error.captureStackTrace ? Error.captureStackTrace(this, this.constructor) : (this.stack = (new Error()).stack);
-  }
-}
index 9ebbe6882ceebcc974e61205591516385f65e241..8f86f478c7aba1c4507b02edd6ab0ac5838edfe8 100644 (file)
@@ -17,7 +17,7 @@ import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStat
 import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus';
 import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration';
 import { OCPPConfigurationKey } from '../../../types/ocpp/Configuration';
-import OCPPError from '../../OCPPError';
+import OCPPError from '../OCPPError';
 import OCPPIncomingRequestService from '../OCPPIncomingRequestService';
 import Utils from '../../../utils/Utils';
 import fs from 'fs';
@@ -43,8 +43,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
       }
     } else {
       // Throw exception
-      await this.chargingStation.ocppRequestService.sendError(messageId, new OCPPError(ErrorType.NOT_IMPLEMENTED, `${commandName} is not implemented`, {}), commandName);
-      throw new Error(`${commandName} is not implemented to handle payload ${JSON.stringify(commandPayload)}`);
+      const errMsg = `${commandName} is not implemented to handle payload ${JSON.stringify(commandPayload, null, 2)}`;
+      await this.chargingStation.ocppRequestService.sendError(messageId, new OCPPError(ErrorType.NOT_IMPLEMENTED, errMsg), commandName);
+      throw new OCPPError(ErrorType.NOT_IMPLEMENTED, errMsg);
     }
     // Send the built response
     await this.chargingStation.ocppRequestService.sendMessage(messageId, response, MessageType.CALL_RESULT_MESSAGE, commandName);
@@ -382,9 +383,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
             }
             return { fileName: diagnosticsArchive };
           }
-          throw new Error(`Diagnostics transfer failed with error code ${accessResponse.code.toString()}${uploadResponse?.code && '|' + uploadResponse?.code.toString()}`);
+          throw new OCPPError(ErrorType.GENERIC_ERROR, `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${uploadResponse?.code && '|' + uploadResponse?.code.toString()}`);
         }
-        throw new Error(`Diagnostics transfer failed with error code ${accessResponse.code.toString()}${uploadResponse?.code && '|' + uploadResponse?.code.toString()}`);
+        throw new OCPPError(ErrorType.GENERIC_ERROR, `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${uploadResponse?.code && '|' + uploadResponse?.code.toString()}`);
       } catch (error) {
         await this.chargingStation.ocppRequestService.sendDiagnosticsStatusNotification(OCPP16DiagnosticsStatus.UploadFailed);
         if (ftpClient) {
index 1f19e858717b097990ceca04f9d3d9a7e73756fc..c28735580a9567db67e7bf0309063eea2fef75f6 100644 (file)
@@ -7,6 +7,7 @@ import { DiagnosticsStatusNotificationRequest, HeartbeatRequest, OCPP16BootNotif
 import { MeterValueUnit, MeterValuesRequest, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16MeterValuePhase } from '../../../types/ocpp/1.6/MeterValues';
 
 import Constants from '../../../utils/Constants';
+import { ErrorType } from '../../../types/ocpp/ErrorType';
 import MeasurandPerPhaseSampledValueTemplates from '../../../types/MeasurandPerPhaseSampledValueTemplates';
 import MeasurandValues from '../../../types/MeasurandValues';
 import { MessageType } from '../../../types/ocpp/MessageType';
@@ -15,7 +16,7 @@ import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointE
 import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
 import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus';
 import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
-import OCPPError from '../../OCPPError';
+import OCPPError from '../OCPPError';
 import OCPPRequestService from '../OCPPRequestService';
 import Utils from '../../../utils/Utils';
 import logger from '../../../utils/Logger';
@@ -221,7 +222,7 @@ export default class OCPP16RequestService extends OCPPRequestService {
             break;
           default:
             logger.error(errMsg);
-            throw new Error(errMsg);
+            throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg);
         }
         meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(powerSampledValueTemplate, powerMeasurandValues.allPhases));
         const sampledValuesIndex = meterValue.sampledValue.length - 1;
@@ -287,7 +288,7 @@ export default class OCPP16RequestService extends OCPPRequestService {
             break;
           default:
             logger.error(errMsg);
-            throw new Error(errMsg);
+            throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg);
         }
         meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(currentSampledValueTemplate, currentMeasurandValues.allPhases));
         const sampledValuesIndex = meterValue.sampledValue.length - 1;
index 4913bd9b18cf891d2d162f0812cb4ac2f9a1e933..896ab74e77792d0283c8921f63373c770ddac758 100644 (file)
@@ -3,6 +3,8 @@
 import { MeterValueContext, MeterValueLocation, MeterValueUnit, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16MeterValuePhase, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues';
 
 import ChargingStation from '../../ChargingStation';
+import { ErrorType } from '../../../types/ocpp/ErrorType';
+import OCPPError from '../OCPPError';
 import { SampledValueTemplate } from '../../../types/Connectors';
 import Utils from '../../../utils/Utils';
 import logger from '../../../utils/Logger';
@@ -12,11 +14,11 @@ export class OCPP16ServiceUtils {
     if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) {
       const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
       logger.error(errMsg);
-      throw new Error(errMsg);
+      throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg);
     } else if (chargingStation.stationInfo?.powerDivider <= 0) {
       const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
       logger.error(errMsg);
-      throw new Error(errMsg);
+      throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg);
     }
   }
 
diff --git a/src/charging-station/ocpp/OCPPError.ts b/src/charging-station/ocpp/OCPPError.ts
new file mode 100644 (file)
index 0000000..b977062
--- /dev/null
@@ -0,0 +1,20 @@
+import { ErrorType } from '../../types/ocpp/ErrorType';
+import { IncomingRequestCommand } from '../../types/ocpp/Requests';
+
+export default class OCPPError extends Error {
+  code: ErrorType | IncomingRequestCommand;
+  details?: unknown;
+
+  constructor(code: ErrorType | IncomingRequestCommand, message: string, details?: unknown) {
+    super(message);
+
+    this.name = new.target.name;
+    this.code = code ?? ErrorType.GENERIC_ERROR;
+    this.message = message ?? '';
+    this.details = details ?? {};
+
+    Object.setPrototypeOf(this, new.target.prototype);
+
+    Error.captureStackTrace ? Error.captureStackTrace(this, this.constructor) : (this.stack = (new Error()).stack);
+  }
+}
index 4c1d1b74f7eeef54fa7aef1e227cc196d7ddd520..ca04745734535776c39ad0e4ae14ab3a1501c9d9 100644 (file)
@@ -9,7 +9,7 @@ import Constants from '../../utils/Constants';
 import { ErrorType } from '../../types/ocpp/ErrorType';
 import { MessageType } from '../../types/ocpp/MessageType';
 import { MeterValue } from '../../types/ocpp/MeterValues';
-import OCPPError from '../OCPPError';
+import OCPPError from './OCPPError';
 import OCPPResponseService from './OCPPResponseService';
 import PerformanceStatistics from '../../utils/PerformanceStatistics';
 import logger from '../../utils/Logger';
index 26d8bd7efbdb4b8469e592b5c08916d4ca7a960f..89f836651c013bc81122326487ac2e4b0070cbc7 100644 (file)
@@ -2,7 +2,7 @@ import { OCPP16AvailabilityType, OCPP16BootNotificationRequest, OCPP16IncomingRe
 
 import { MessageType } from './MessageType';
 import { OCPP16DiagnosticsStatus } from './1.6/DiagnosticsStatus';
-import OCPPError from '../../charging-station/OCPPError';
+import OCPPError from '../../charging-station/ocpp/OCPPError';
 
 export default interface Requests {
   [id: string]: Request;