} from '../types/ocpp/Requests';
 import {
   BootNotificationResponse,
+  ErrorResponse,
   HeartbeatResponse,
   MeterValuesResponse,
   RegistrationStatus,
+  Response,
   StatusNotificationResponse,
 } from '../types/ocpp/Responses';
 import {
   }
 
   private async onMessage(data: Data): Promise<void> {
-    let [messageType, messageId, commandName, commandPayload, errorDetails]: IncomingRequest = [
-      0,
-      '',
-      '' as IncomingRequestCommand,
-      {},
-      {},
-    ];
-    let responseCallback: (
-      payload: JsonType | string,
-      requestPayload: JsonType | OCPPError
-    ) => void;
+    let messageType: number;
+    let messageId: string;
+    let commandName: IncomingRequestCommand;
+    let commandPayload: JsonType;
+    let errorType: ErrorType;
+    let errorMessage: string;
+    let errorDetails: JsonType;
+    let responseCallback: (payload: JsonType, requestPayload: JsonType) => void;
     let rejectCallback: (error: OCPPError, requestStatistic?: boolean) => void;
     let requestCommandName: RequestCommand | IncomingRequestCommand;
-    let requestPayload: JsonType | OCPPError;
+    let requestPayload: JsonType;
     let cachedRequest: CachedRequest;
     let errMsg: string;
     try {
-      const request = JSON.parse(data.toString()) as IncomingRequest;
+      const request = JSON.parse(data.toString()) as IncomingRequest | Response | ErrorResponse;
       if (Utils.isIterable(request)) {
-        // Parse the message
-        [messageType, messageId, commandName, commandPayload, errorDetails] = request;
+        [messageType] = request;
+        // Check the type of message
+        switch (messageType) {
+          // Incoming Message
+          case MessageType.CALL_MESSAGE:
+            [, messageId, commandName, commandPayload] = request as IncomingRequest;
+            if (this.getEnableStatistics()) {
+              this.performanceStatistics.addRequestStatistic(commandName, messageType);
+            }
+            logger.debug(
+              `${this.logPrefix()} << Command '${commandName}' received request payload: ${JSON.stringify(
+                request
+              )}`
+            );
+            // Process the message
+            await this.ocppIncomingRequestService.incomingRequestHandler(
+              messageId,
+              commandName,
+              commandPayload
+            );
+            break;
+          // Outcome Message
+          case MessageType.CALL_RESULT_MESSAGE:
+            [, messageId, commandPayload] = request as Response;
+            // Respond
+            cachedRequest = this.requests.get(messageId);
+            if (Utils.isIterable(cachedRequest)) {
+              [responseCallback, , requestCommandName, requestPayload] = cachedRequest;
+            } else {
+              throw new OCPPError(
+                ErrorType.PROTOCOL_ERROR,
+                `Cached request for message id ${messageId} response is not iterable`,
+                requestCommandName
+              );
+            }
+            logger.debug(
+              `${this.logPrefix()} << Command '${requestCommandName}' received response payload: ${JSON.stringify(
+                request
+              )}`
+            );
+            if (!responseCallback) {
+              // Error
+              throw new OCPPError(
+                ErrorType.INTERNAL_ERROR,
+                `Response for unknown message id ${messageId}`,
+                requestCommandName
+              );
+            }
+            responseCallback(commandPayload, requestPayload);
+            break;
+          // Error Message
+          case MessageType.CALL_ERROR_MESSAGE:
+            [, messageId, errorType, errorMessage, errorDetails] = request as ErrorResponse;
+            cachedRequest = this.requests.get(messageId);
+            if (Utils.isIterable(cachedRequest)) {
+              [, rejectCallback, requestCommandName] = cachedRequest;
+            } else {
+              throw new OCPPError(
+                ErrorType.PROTOCOL_ERROR,
+                `Cached request for message id ${messageId} error response is not iterable`
+              );
+            }
+            logger.debug(
+              `${this.logPrefix()} << Command '${requestCommandName}' received error payload: ${JSON.stringify(
+                request
+              )}`
+            );
+            if (!rejectCallback) {
+              // Error
+              throw new OCPPError(
+                ErrorType.INTERNAL_ERROR,
+                `Error response for unknown message id ${messageId}`,
+                requestCommandName
+              );
+            }
+            rejectCallback(
+              new OCPPError(errorType, errorMessage, requestCommandName, errorDetails)
+            );
+            break;
+          // Error
+          default:
+            // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+            errMsg = `${this.logPrefix()} Wrong message type ${messageType}`;
+            logger.error(errMsg);
+            throw new OCPPError(ErrorType.PROTOCOL_ERROR, errMsg);
+        }
       } else {
         throw new OCPPError(
           ErrorType.PROTOCOL_ERROR,
           'Incoming message is not iterable',
-          Utils.isString(commandName) && commandName,
+          Utils.isString(commandName) ? commandName : requestCommandName,
           { payload: request }
         );
       }
-      // Check the Type of message
-      switch (messageType) {
-        // Incoming Message
-        case MessageType.CALL_MESSAGE:
-          if (this.getEnableStatistics()) {
-            this.performanceStatistics.addRequestStatistic(commandName, messageType);
-          }
-          logger.debug(
-            `${this.logPrefix()} << Command '${commandName}' received request payload: ${JSON.stringify(
-              request
-            )}`
-          );
-          // Process the call
-          await this.ocppIncomingRequestService.incomingRequestHandler(
-            messageId,
-            commandName,
-            commandPayload
-          );
-          break;
-        // Outcome Message
-        case MessageType.CALL_RESULT_MESSAGE:
-          // Respond
-          cachedRequest = this.requests.get(messageId);
-          if (Utils.isIterable(cachedRequest)) {
-            [responseCallback, , requestCommandName, requestPayload] = cachedRequest;
-          } else {
-            throw new OCPPError(
-              ErrorType.PROTOCOL_ERROR,
-              `Cached request for message id ${messageId} response is not iterable`,
-              requestCommandName
-            );
-          }
-          logger.debug(
-            `${this.logPrefix()} << Command '${requestCommandName}' received response payload: ${JSON.stringify(
-              request
-            )}`
-          );
-          if (!responseCallback) {
-            // Error
-            throw new OCPPError(
-              ErrorType.INTERNAL_ERROR,
-              `Response for unknown message id ${messageId}`,
-              requestCommandName
-            );
-          }
-          responseCallback(commandName, requestPayload);
-          break;
-        // Error Message
-        case MessageType.CALL_ERROR_MESSAGE:
-          cachedRequest = this.requests.get(messageId);
-          if (Utils.isIterable(cachedRequest)) {
-            [, rejectCallback, requestCommandName] = cachedRequest;
-          } else {
-            throw new OCPPError(
-              ErrorType.PROTOCOL_ERROR,
-              `Cached request for message id ${messageId} error response is not iterable`
-            );
-          }
-          logger.debug(
-            `${this.logPrefix()} << Command '${requestCommandName}' received error payload: ${JSON.stringify(
-              request
-            )}`
-          );
-          if (!rejectCallback) {
-            // Error
-            throw new OCPPError(
-              ErrorType.INTERNAL_ERROR,
-              `Error response for unknown message id ${messageId}`,
-              requestCommandName
-            );
-          }
-          rejectCallback(
-            new OCPPError(commandName, commandPayload.toString(), requestCommandName, errorDetails)
-          );
-          break;
-        // Error
-        default:
-          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-          errMsg = `${this.logPrefix()} Wrong message type ${messageType}`;
-          logger.error(errMsg);
-          throw new OCPPError(ErrorType.PROTOCOL_ERROR, errMsg);
-      }
     } catch (error) {
       // Log
       logger.error(
       );
       // Send error
       messageType === MessageType.CALL_MESSAGE &&
-        (await this.ocppRequestService.sendError(messageId, error as OCPPError, commandName));
+        (await this.ocppRequestService.sendError(
+          messageId,
+          error as OCPPError,
+          Utils.isString(commandName) ? commandName : requestCommandName
+        ));
     }
   }
 
 
+import { ErrorResponse, Response } from '../../types/ocpp/Responses';
 import {
   IncomingRequestCommand,
+  OutgoingRequest,
   RequestCommand,
   RequestParams,
   ResponseType,
   public async sendError(
     messageId: string,
     ocppError: OCPPError,
-    commandName: IncomingRequestCommand
+    commandName: RequestCommand | IncomingRequestCommand
   ): Promise<ResponseType> {
     try {
       // Send error message
            * @param requestPayload
            */
           async function responseCallback(
-            payload: JsonType | string,
+            payload: JsonType,
             requestPayload: JsonType
           ): Promise<void> {
             if (self.chargingStation.getEnableStatistics()) {
     messagePayload: JsonType | OCPPError,
     messageType: MessageType,
     commandName?: RequestCommand | IncomingRequestCommand,
-    responseCallback?: (payload: JsonType | string, requestPayload: JsonType) => Promise<void>,
+    responseCallback?: (payload: JsonType, requestPayload: JsonType) => Promise<void>,
     rejectCallback?: (error: OCPPError, requestStatistic?: boolean) => void
   ): string {
     let messageToSend: string;
           responseCallback,
           rejectCallback,
           commandName,
-          messagePayload,
+          messagePayload as JsonType,
         ]);
-        messageToSend = JSON.stringify([messageType, messageId, commandName, messagePayload]);
+        messageToSend = JSON.stringify([
+          messageType,
+          messageId,
+          commandName,
+          messagePayload,
+        ] as OutgoingRequest);
         break;
       // Response
       case MessageType.CALL_RESULT_MESSAGE:
         // Build response
-        messageToSend = JSON.stringify([messageType, messageId, messagePayload]);
+        messageToSend = JSON.stringify([messageType, messageId, messagePayload] as Response);
         break;
       // Error Message
       case MessageType.CALL_ERROR_MESSAGE:
         messageToSend = JSON.stringify([
           messageType,
           messageId,
-          messagePayload?.code ?? ErrorType.GENERIC_ERROR,
-          messagePayload?.message ?? '',
-          messagePayload?.details ?? { commandName },
-        ]);
+          (messagePayload as OCPPError)?.code ?? ErrorType.GENERIC_ERROR,
+          (messagePayload as OCPPError)?.message ?? '',
+          (messagePayload as OCPPError)?.details ?? { commandName },
+        ] as ErrorResponse);
         break;
     }
     return messageToSend;
 
 import { OCPP16MeterValuesRequest } from './1.6/MeterValues';
 import OCPPError from '../../exception/OCPPError';
 
+export type OutgoingRequest = [MessageType.CALL_MESSAGE, string, RequestCommand, JsonType];
+
+export type IncomingRequest = [MessageType.CALL_MESSAGE, string, IncomingRequestCommand, JsonType];
+
+export type CachedRequest = [
+  (payload: JsonType, requestPayload: JsonType) => void,
+  (error: OCPPError, requestStatistic?: boolean) => void,
+  RequestCommand | IncomingRequestCommand,
+  JsonType
+];
+
+export type IncomingRequestHandler = (commandPayload: JsonType) => JsonType | Promise<JsonType>;
+
+export type ResponseType = JsonType | OCPPError;
+
 export interface RequestParams {
   skipBufferingOnError?: boolean;
   triggerMessage?: boolean;
 }
 
-export type IncomingRequestHandler = (commandPayload: JsonType) => JsonType | Promise<JsonType>;
-
-export type ResponseType = JsonType | OCPPError | string;
-
 export type BootNotificationRequest = OCPP16BootNotificationRequest;
 
 export type HeartbeatRequest = OCPP16HeartbeatRequest;
 export const DiagnosticsStatus = {
   ...OCPP16DiagnosticsStatus,
 };
-
-export type Request = [MessageType, string, RequestCommand, JsonType, JsonType];
-
-export type IncomingRequest = [MessageType, string, IncomingRequestCommand, JsonType, JsonType];
-
-export type CachedRequest = [
-  (payload: JsonType, requestPayload: JsonType) => void,
-  (error: OCPPError, requestStatistic?: boolean) => void,
-  RequestCommand | IncomingRequestCommand,
-  JsonType | OCPPError
-];