X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Focpp%2FOCPPRequestService.ts;h=f561a44635c16f4088503dbf01961143faca484f;hb=b2a0452d368cfc43bbacc4991de59afa64f662a4;hp=6c0e7b0db4c571064ffb4ceacf474841df0df526;hpb=b3fc3ff5bc50c2dbe20eb3ac1e681c00a022b4ee;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ocpp/OCPPRequestService.ts b/src/charging-station/ocpp/OCPPRequestService.ts index 6c0e7b0d..f561a446 100644 --- a/src/charging-station/ocpp/OCPPRequestService.ts +++ b/src/charging-station/ocpp/OCPPRequestService.ts @@ -1,6 +1,8 @@ import Ajv, { type JSONSchemaType } from 'ajv'; import ajvFormats from 'ajv-formats'; +import type OCPPResponseService from './OCPPResponseService'; +import { OCPPServiceUtils } from './OCPPServiceUtils'; import OCPPError from '../../exception/OCPPError'; import PerformanceStatistics from '../../performance/PerformanceStatistics'; import type { EmptyObject } from '../../types/EmptyObject'; @@ -23,8 +25,6 @@ import Constants from '../../utils/Constants'; import logger from '../../utils/Logger'; import Utils from '../../utils/Utils'; import type ChargingStation from '../ChargingStation'; -import type OCPPResponseService from './OCPPResponseService'; -import { OCPPServiceUtils } from './OCPPServiceUtils'; const moduleName = 'OCPPRequestService'; @@ -50,6 +50,7 @@ export default abstract class OCPPRequestService { this.internalSendMessage.bind(this); this.buildMessageToSend.bind(this); this.validateRequestPayload.bind(this); + this.validateIncomingRequestResponsePayload.bind(this); } public static getInstance( @@ -112,6 +113,7 @@ export default abstract class OCPPRequestService { params: RequestParams = { skipBufferingOnError: false, triggerMessage: false, + throwError: false, } ): Promise { try { @@ -124,11 +126,13 @@ export default abstract class OCPPRequestService { params ); } catch (error) { - this.handleSendMessageError(chargingStation, commandName, error as Error); + this.handleSendMessageError(chargingStation, commandName, error as Error, { + throwError: params.throwError, + }); } } - protected validateRequestPayload( + private validateRequestPayload( chargingStation: ChargingStation, commandName: RequestCommand | IncomingRequestCommand, payload: T @@ -161,7 +165,7 @@ export default abstract class OCPPRequestService { ); } - protected validateResponsePayload( + private validateIncomingRequestResponsePayload( chargingStation: ChargingStation, commandName: RequestCommand | IncomingRequestCommand, payload: T @@ -175,7 +179,7 @@ export default abstract class OCPPRequestService { ) === false ) { logger.warn( - `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: No JSON schema found for command '${commandName}' PDU validation` + `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestResponsePayload: No JSON schema found for command '${commandName}' PDU validation` ); return true; } @@ -190,7 +194,7 @@ export default abstract class OCPPRequestService { return true; } logger.error( - `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' reponse PDU is invalid: %j`, + `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestResponsePayload: Command '${commandName}' reponse PDU is invalid: %j`, validate.errors ); // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). @@ -239,47 +243,52 @@ export default abstract class OCPPRequestService { if (chargingStation.getEnableStatistics() === true) { chargingStation.performanceStatistics.addRequestStatistic(commandName, messageType); } + let sendError = false; // Check if wsConnection opened if (chargingStation.isWebSocketConnectionOpened() === true) { - // Yes: Send Message const beginId = PerformanceStatistics.beginMeasure(commandName as string); - // FIXME: Handle sending error - chargingStation.wsConnection.send(messageToSend); + try { + chargingStation.wsConnection.send(messageToSend); + } catch (error) { + sendError = true; + } PerformanceStatistics.endMeasure(commandName as string, beginId); logger.debug( `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${this.getMessageTypeString( messageType )} payload: ${messageToSend}` ); - } else if (params.skipBufferingOnError === false) { - // Buffer it + } + const wsClosedOrErrored = + chargingStation.isWebSocketConnectionOpened() === false || sendError === true; + if (wsClosedOrErrored && params.skipBufferingOnError === false) { + // Buffer chargingStation.bufferMessage(messageToSend); + // Reject and keep request in the cache + return reject( + new OCPPError( + ErrorType.GENERIC_ERROR, + `WebSocket closed or errored for buffered message id '${messageId}' with content '${messageToSend}'`, + commandName, + (messagePayload as JsonObject)?.details ?? {} + ) + ); + } else if (wsClosedOrErrored) { const ocppError = new OCPPError( ErrorType.GENERIC_ERROR, - `WebSocket closed for buffered message id '${messageId}' with content '${messageToSend}'`, + `WebSocket closed or errored for non buffered message id '${messageId}' with content '${messageToSend}'`, commandName, (messagePayload as JsonObject)?.details ?? {} ); - if (messageType === MessageType.CALL_MESSAGE) { - // Reject it but keep the request in the cache + // Reject response + if (messageType !== MessageType.CALL_MESSAGE) { return reject(ocppError); } + // Reject and remove request from the cache return errorCallback(ocppError, false); - } else { - // Reject it - return errorCallback( - new OCPPError( - ErrorType.GENERIC_ERROR, - `WebSocket closed for non buffered message id '${messageId}' with content '${messageToSend}'`, - commandName, - (messagePayload as JsonObject)?.details ?? {} - ), - false - ); } - // Response? + // Resolve response if (messageType !== MessageType.CALL_MESSAGE) { - // Yes: send Ok return resolve(messagePayload); } @@ -329,9 +338,10 @@ export default abstract class OCPPRequestService { ); } logger.error( - `${chargingStation.logPrefix()} Error occurred when calling command ${commandName} with message data ${JSON.stringify( - messagePayload - )}:`, + `${chargingStation.logPrefix()} Error occurred at ${self.getMessageTypeString( + messageType + )} command ${commandName} with PDU %j:`, + messagePayload, error ); chargingStation.requests.delete(messageId); @@ -389,7 +399,11 @@ export default abstract class OCPPRequestService { // Response case MessageType.CALL_RESULT_MESSAGE: // Build response - this.validateResponsePayload(chargingStation, commandName, messagePayload as JsonObject); + this.validateIncomingRequestResponsePayload( + chargingStation, + commandName, + messagePayload as JsonObject + ); messageToSend = JSON.stringify([messageType, messageId, messagePayload] as Response); break; // Error Message