From 14763b466177d8e74d2e1925647e04e2d62ac72a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 29 Aug 2021 18:01:06 +0200 Subject: [PATCH] Refine and use OCPP error specialisation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/charging-station/ChargingStation.ts | 15 +++++++------- src/charging-station/OCPPError.ts | 18 ----------------- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 11 +++++----- .../ocpp/1.6/OCPP16RequestService.ts | 7 ++++--- .../ocpp/1.6/OCPP16ServiceUtils.ts | 6 ++++-- src/charging-station/ocpp/OCPPError.ts | 20 +++++++++++++++++++ .../ocpp/OCPPRequestService.ts | 2 +- src/types/ocpp/Requests.ts | 2 +- 8 files changed, 44 insertions(+), 37 deletions(-) delete mode 100644 src/charging-station/OCPPError.ts create mode 100644 src/charging-station/ocpp/OCPPError.ts diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index ebb53a9f..1626a9b3 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -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 index 6780b60b..00000000 --- a/src/charging-station/OCPPError.ts +++ /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); - } -} diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index 9ebbe688..8f86f478 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -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) { diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 1f19e858..c2873558 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -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; diff --git a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts index 4913bd9b..896ab74e 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts @@ -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 index 00000000..b977062a --- /dev/null +++ b/src/charging-station/ocpp/OCPPError.ts @@ -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); + } +} diff --git a/src/charging-station/ocpp/OCPPRequestService.ts b/src/charging-station/ocpp/OCPPRequestService.ts index 4c1d1b74..ca047457 100644 --- a/src/charging-station/ocpp/OCPPRequestService.ts +++ b/src/charging-station/ocpp/OCPPRequestService.ts @@ -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'; diff --git a/src/types/ocpp/Requests.ts b/src/types/ocpp/Requests.ts index 26d8bd7e..89f83665 100644 --- a/src/types/ocpp/Requests.ts +++ b/src/types/ocpp/Requests.ts @@ -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; -- 2.34.1