build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / utils / ErrorUtils.ts
1 import process from 'node:process'
2
3 import chalk from 'chalk'
4
5 import type { ChargingStation } from '../charging-station/index.js'
6 import { getMessageTypeString } from '../charging-station/ocpp/OCPPServiceUtils.js'
7 import type {
8 EmptyObject,
9 FileType,
10 HandleErrorParams,
11 IncomingRequestCommand,
12 JsonType,
13 MessageType,
14 RequestCommand
15 } from '../types/index.js'
16 import { logger } from './Logger.js'
17 import { isNotEmptyString } from './Utils.js'
18
19 const moduleName = 'ErrorUtils'
20
21 const defaultErrorParams = {
22 throwError: true,
23 consoleOut: false
24 } satisfies HandleErrorParams<EmptyObject>
25
26 export const handleUncaughtException = (): void => {
27 process.on('uncaughtException', (error: Error) => {
28 console.error(chalk.red('Uncaught exception: '), error)
29 })
30 }
31
32 export const handleUnhandledRejection = (): void => {
33 process.on('unhandledRejection', (reason: unknown) => {
34 console.error(chalk.red('Unhandled rejection: '), reason)
35 })
36 }
37
38 export const handleFileException = (
39 file: string,
40 fileType: FileType,
41 error: NodeJS.ErrnoException,
42 logPrefix: string,
43 params: HandleErrorParams<EmptyObject> = defaultErrorParams
44 ): void => {
45 params = setDefaultErrorParams(params)
46 const prefix = isNotEmptyString(logPrefix) ? `${logPrefix} ` : ''
47 let logMsg: string
48 switch (error.code) {
49 case 'ENOENT':
50 logMsg = `${fileType} file ${file} not found:`
51 break
52 case 'EEXIST':
53 logMsg = `${fileType} file ${file} already exists:`
54 break
55 case 'EACCES':
56 logMsg = `${fileType} file ${file} access denied:`
57 break
58 case 'EPERM':
59 logMsg = `${fileType} file ${file} permission denied:`
60 break
61 default:
62 logMsg = `${fileType} file ${file} error:`
63 }
64 if (params.consoleOut === true) {
65 logMsg = `${logMsg} `
66 if (params.throwError === true) {
67 console.error(`${chalk.green(prefix)}${chalk.red(logMsg)}`, error)
68 } else {
69 console.warn(`${chalk.green(prefix)}${chalk.yellow(logMsg)}`, error)
70 }
71 } else if (params.consoleOut === false) {
72 if (params.throwError === true) {
73 logger.error(`${prefix}${logMsg}`, error)
74 } else {
75 logger.warn(`${prefix}${logMsg}`, error)
76 }
77 }
78 if (params.throwError === true) {
79 throw error
80 }
81 }
82
83 export const handleSendMessageError = (
84 chargingStation: ChargingStation,
85 commandName: RequestCommand | IncomingRequestCommand,
86 messageType: MessageType,
87 error: Error,
88 params: HandleErrorParams<EmptyObject> = {
89 throwError: false,
90 consoleOut: false
91 }
92 ): void => {
93 params = setDefaultErrorParams(params, { throwError: false, consoleOut: false })
94 logger.error(
95 `${chargingStation.logPrefix()} ${moduleName}.handleSendMessageError: Send ${getMessageTypeString(messageType)} command '${commandName}' error:`,
96 error
97 )
98 if (params.throwError === true) {
99 throw error
100 }
101 }
102
103 export const handleIncomingRequestError = <T extends JsonType>(
104 chargingStation: ChargingStation,
105 commandName: IncomingRequestCommand,
106 error: Error,
107 params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
108 ): T | undefined => {
109 params = setDefaultErrorParams(params)
110 logger.error(
111 `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
112 error
113 )
114 if (params.throwError === false && params.errorResponse != null) {
115 return params.errorResponse
116 }
117 if (params.throwError === true && params.errorResponse == null) {
118 throw error
119 }
120 if (params.throwError === true && params.errorResponse != null) {
121 return params.errorResponse
122 }
123 }
124
125 export const setDefaultErrorParams = <T extends JsonType>(
126 params: HandleErrorParams<T>,
127 defaultParams: HandleErrorParams<T> = defaultErrorParams
128 ): HandleErrorParams<T> => {
129 return { ...defaultParams, ...params }
130 }