@sap-ux/odata-service-inquirer 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -6
- package/dist/prompts/connectionValidator.d.ts +1 -1
- package/dist/prompts/connectionValidator.js +25 -25
- package/dist/prompts/datasources/cap-project/questions.js +2 -1
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.d.ts +1 -1
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.js +8 -10
- package/dist/prompts/datasources/sap-system/credentials/questions.d.ts +2 -2
- package/dist/prompts/datasources/sap-system/credentials/questions.js +2 -2
- package/dist/prompts/datasources/sap-system/service-selection/questions.js +4 -4
- package/dist/prompts/datasources/sap-system/service-selection/service-helper.js +3 -2
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.js +3 -3
- package/dist/prompts/datasources/sap-system/system-selection/questions.js +2 -1
- package/dist/prompts/datasources/service-url/questions.js +2 -1
- package/dist/prompts/datasources/service-url/validators.js +3 -3
- package/dist/prompts/prompt-helpers.d.ts +1 -1
- package/dist/prompts/prompt-helpers.js +2 -2
- package/dist/translations/odata-service-inquirer.i18n.json +4 -37
- package/dist/types.d.ts +0 -35
- package/dist/types.js +1 -41
- package/dist/utils/index.d.ts +3 -25
- package/dist/utils/index.js +5 -72
- package/package.json +6 -5
- package/dist/error-handler/error-handler.d.ts +0 -206
- package/dist/error-handler/error-handler.js +0 -567
- package/dist/prompts/datasources/sap-system/abap-on-btp/cf-helper.d.ts +0 -9
- package/dist/prompts/datasources/sap-system/abap-on-btp/cf-helper.js +0 -54
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ErrorHandler = exports.ERROR_MAP = exports.ERROR_TYPE = void 0;
|
|
4
|
-
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
5
|
-
const guided_answers_helper_1 = require("@sap-ux/guided-answers-helper");
|
|
6
|
-
const logger_1 = require("@sap-ux/logger");
|
|
7
|
-
const i18n_1 = require("../i18n");
|
|
8
|
-
const types_1 = require("../types");
|
|
9
|
-
const utils_1 = require("../utils");
|
|
10
|
-
// Telemetry event names specific to odata service error handling
|
|
11
|
-
const telemEventGALinkCreated = 'GA_LINK_CREATED';
|
|
12
|
-
const telemBasError = 'SERVICE_INQUIRER_BAS_ERROR';
|
|
13
|
-
/**
|
|
14
|
-
* Constants specific to error handling
|
|
15
|
-
*/
|
|
16
|
-
var ERROR_TYPE;
|
|
17
|
-
(function (ERROR_TYPE) {
|
|
18
|
-
ERROR_TYPE["AUTH"] = "AUTH";
|
|
19
|
-
ERROR_TYPE["AUTH_TIMEOUT"] = "AUTH_TIMEOUT";
|
|
20
|
-
ERROR_TYPE["REDIRECT"] = "REDIRECT";
|
|
21
|
-
ERROR_TYPE["CERT"] = "CERT";
|
|
22
|
-
ERROR_TYPE["CERT_SELF_SIGNED"] = "CERT_SELF_SIGNED";
|
|
23
|
-
ERROR_TYPE["CERT_UKNOWN_OR_INVALID"] = "CERT_UKNOWN_OR_INVALID";
|
|
24
|
-
ERROR_TYPE["CERT_EXPIRED"] = "CERT_EXPIRED";
|
|
25
|
-
ERROR_TYPE["CERT_SELF_SIGNED_CERT_IN_CHAIN"] = "CERT_SELF_SIGNED_CERT_IN_CHAIN";
|
|
26
|
-
ERROR_TYPE["UNKNOWN"] = "UNKNOWN";
|
|
27
|
-
ERROR_TYPE["INVALID_URL"] = "INVALID_URL";
|
|
28
|
-
ERROR_TYPE["TIMEOUT"] = "TIMEOUT";
|
|
29
|
-
ERROR_TYPE["CONNECTION"] = "CONNECTION";
|
|
30
|
-
ERROR_TYPE["SERVICES_UNAVAILABLE"] = "SERVICES_UNAVAILABLE";
|
|
31
|
-
ERROR_TYPE["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
|
32
|
-
ERROR_TYPE["NO_ABAP_ENVS"] = "NO_ABAP_ENVS";
|
|
33
|
-
ERROR_TYPE["CATALOG_SERVICE_NOT_ACTIVE"] = "CATALOG_SERVICE_NOT_ACTIVE";
|
|
34
|
-
ERROR_TYPE["NO_SUCH_HOST"] = "NO_SUCH_HOST";
|
|
35
|
-
ERROR_TYPE["NOT_FOUND"] = "NOT_FOUND";
|
|
36
|
-
ERROR_TYPE["ODATA_URL_NOT_FOUND"] = "ODATA_URL_NOT_FOUND";
|
|
37
|
-
ERROR_TYPE["BAD_GATEWAY"] = "BAD_GATEWAY";
|
|
38
|
-
ERROR_TYPE["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
39
|
-
ERROR_TYPE["DESTINATION_BAD_GATEWAY_503"] = "DESTINATION_BAD_GATEWAY_503";
|
|
40
|
-
ERROR_TYPE["DESTINATION_UNAVAILABLE"] = "DESTINATION_UNAVAILABLE";
|
|
41
|
-
ERROR_TYPE["DESTINATION_NOT_FOUND"] = "DESTINATION_NOT_FOUND";
|
|
42
|
-
ERROR_TYPE["DESTINATION_MISCONFIGURED"] = "DESTINATION_MISCONFIGURED";
|
|
43
|
-
ERROR_TYPE["NO_V2_SERVICES"] = "NO_V2_SERVICES";
|
|
44
|
-
ERROR_TYPE["NO_V4_SERVICES"] = "NO_V4_SERVICES";
|
|
45
|
-
ERROR_TYPE["BAD_REQUEST"] = "BAD_REQUEST";
|
|
46
|
-
ERROR_TYPE["DESTINATION_CONNECTION_ERROR"] = "DESTINATION_CONNECTION_ERROR";
|
|
47
|
-
ERROR_TYPE["SERVER_HTTP_ERROR"] = "SERVER_HTTP_ERROR";
|
|
48
|
-
})(ERROR_TYPE || (exports.ERROR_TYPE = ERROR_TYPE = {}));
|
|
49
|
-
// Used to match regex expressions to error messages, etc. providing a way to return a consistent
|
|
50
|
-
// single error and error msg for multiple errors
|
|
51
|
-
exports.ERROR_MAP = {
|
|
52
|
-
[ERROR_TYPE.AUTH]: [
|
|
53
|
-
/401/,
|
|
54
|
-
/403/,
|
|
55
|
-
/Incorrect credentials were provided to login/, // API Hub error msg
|
|
56
|
-
/Unable to retrieve SAP Business Accelerator Hub key/ // API Hub error msg
|
|
57
|
-
],
|
|
58
|
-
[ERROR_TYPE.AUTH_TIMEOUT]: [/UAATimeoutError/],
|
|
59
|
-
[ERROR_TYPE.TIMEOUT]: [/Timeout/],
|
|
60
|
-
[ERROR_TYPE.CERT]: [], // General cert error, unspecified root cause
|
|
61
|
-
[ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: [
|
|
62
|
-
/UNABLE_TO_GET_ISSUER_CERT/,
|
|
63
|
-
/UNABLE_TO_GET_ISSUER_CERT_LOCALLY/,
|
|
64
|
-
/unable to get local issuer certificate/
|
|
65
|
-
],
|
|
66
|
-
[ERROR_TYPE.CERT_EXPIRED]: [/CERT_HAS_EXPIRED/],
|
|
67
|
-
[ERROR_TYPE.CERT_SELF_SIGNED]: [/DEPTH_ZERO_SELF_SIGNED_CERT/],
|
|
68
|
-
[ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: [/SELF_SIGNED_CERT_IN_CHAIN/],
|
|
69
|
-
[ERROR_TYPE.UNKNOWN]: [],
|
|
70
|
-
[ERROR_TYPE.CONNECTION]: [/ENOTFOUND/, /ECONNRESET/, /ECONNREFUSED/, /ConnectionError/],
|
|
71
|
-
[ERROR_TYPE.SERVICES_UNAVAILABLE]: [],
|
|
72
|
-
[ERROR_TYPE.SERVICE_UNAVAILABLE]: [/503/],
|
|
73
|
-
[ERROR_TYPE.INVALID_URL]: [/Invalid URL/, /ERR_INVALID_URL/],
|
|
74
|
-
[ERROR_TYPE.REDIRECT]: [/3[\d][\d]/],
|
|
75
|
-
[ERROR_TYPE.NO_ABAP_ENVS]: [],
|
|
76
|
-
[ERROR_TYPE.CATALOG_SERVICE_NOT_ACTIVE]: [
|
|
77
|
-
/\/IWBEP\/CM_V4_COS\/014/,
|
|
78
|
-
/\/IWFND\/CM_V4_COS\/021/,
|
|
79
|
-
/Service group '\/IWFND\/CONFIG' not published/
|
|
80
|
-
],
|
|
81
|
-
[ERROR_TYPE.NO_SUCH_HOST]: [/no such host/],
|
|
82
|
-
[ERROR_TYPE.NOT_FOUND]: [/404/],
|
|
83
|
-
[ERROR_TYPE.ODATA_URL_NOT_FOUND]: [],
|
|
84
|
-
[ERROR_TYPE.INTERNAL_SERVER_ERROR]: [/500/],
|
|
85
|
-
[ERROR_TYPE.BAD_GATEWAY]: [/502/],
|
|
86
|
-
[ERROR_TYPE.DESTINATION_BAD_GATEWAY_503]: [],
|
|
87
|
-
[ERROR_TYPE.DESTINATION_UNAVAILABLE]: [],
|
|
88
|
-
[ERROR_TYPE.DESTINATION_NOT_FOUND]: [],
|
|
89
|
-
[ERROR_TYPE.DESTINATION_MISCONFIGURED]: [],
|
|
90
|
-
[ERROR_TYPE.NO_V2_SERVICES]: [],
|
|
91
|
-
[ERROR_TYPE.NO_V4_SERVICES]: [],
|
|
92
|
-
[ERROR_TYPE.BAD_REQUEST]: [/400/],
|
|
93
|
-
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: [],
|
|
94
|
-
[ERROR_TYPE.SERVER_HTTP_ERROR]: [/5\d\d/] // catch all for 5xx server errors
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Maps errors to end-user messages using some basic root cause analysis based on regex matching.
|
|
98
|
-
* This class will also log errors and provide help links for validation errors in some limited use cases.
|
|
99
|
-
*/
|
|
100
|
-
class ErrorHandler {
|
|
101
|
-
/** The last error message generated */
|
|
102
|
-
currentErrorMsg;
|
|
103
|
-
/** The last error message type generated if determined */
|
|
104
|
-
currentErrorType;
|
|
105
|
-
static _guidedAnswersEnabled;
|
|
106
|
-
static _logger;
|
|
107
|
-
static getMessageFromError = (error) => {
|
|
108
|
-
return (error?.message ||
|
|
109
|
-
error?.status?.toString() ||
|
|
110
|
-
error?.response?.status?.toString() ||
|
|
111
|
-
(typeof error === 'string' ? error : JSON.stringify(error)));
|
|
112
|
-
};
|
|
113
|
-
// Get the localized parameterized error message for the specified error type
|
|
114
|
-
static _errorTypeToMsg = {
|
|
115
|
-
[ERROR_TYPE.CERT]: (error) => (0, i18n_1.t)('errors.certificateError', { error: typeof error === 'string' ? error : JSON.stringify(error) }),
|
|
116
|
-
[ERROR_TYPE.CERT_EXPIRED]: () => (0, i18n_1.t)('errors.urlCertValidationError', { certErrorReason: (0, i18n_1.t)('texts.anExpiredCert') }),
|
|
117
|
-
[ERROR_TYPE.CERT_SELF_SIGNED]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
118
|
-
certErrorReason: (0, i18n_1.t)('texts.aSelfSignedCert')
|
|
119
|
-
}),
|
|
120
|
-
[ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
121
|
-
certErrorReason: (0, i18n_1.t)('texts.anUnknownOrInvalidCert')
|
|
122
|
-
}),
|
|
123
|
-
[ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
124
|
-
certErrorReason: (0, i18n_1.t)('texts.anUntrustedRootCert')
|
|
125
|
-
}),
|
|
126
|
-
[ERROR_TYPE.AUTH]: (error) => (0, i18n_1.t)('errors.authenticationFailed', {
|
|
127
|
-
error: ErrorHandler.getMessageFromError(error)
|
|
128
|
-
}),
|
|
129
|
-
[ERROR_TYPE.AUTH_TIMEOUT]: () => (0, i18n_1.t)('errors.authenticationTimeout'),
|
|
130
|
-
[ERROR_TYPE.TIMEOUT]: (error) => (0, i18n_1.t)('errors.timeout', { error: typeof error === 'string' ? error : JSON.stringify(error) }),
|
|
131
|
-
[ERROR_TYPE.INVALID_URL]: () => (0, i18n_1.t)('errors.invalidUrl'),
|
|
132
|
-
[ERROR_TYPE.CONNECTION]: (error) => (0, i18n_1.t)('errors.connectionError', {
|
|
133
|
-
error: ErrorHandler.getMessageFromError(error)
|
|
134
|
-
}),
|
|
135
|
-
[ERROR_TYPE.UNKNOWN]: (error) => (0, i18n_1.t)('errors.unknownError', {
|
|
136
|
-
error: ErrorHandler.getMessageFromError(error)
|
|
137
|
-
}),
|
|
138
|
-
[ERROR_TYPE.SERVICES_UNAVAILABLE]: () => (0, i18n_1.t)('errors.servicesUnavailable'),
|
|
139
|
-
[ERROR_TYPE.SERVICE_UNAVAILABLE]: (error) => (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
140
|
-
errorMsg: ErrorHandler.getMessageFromError(error)
|
|
141
|
-
}),
|
|
142
|
-
[ERROR_TYPE.CATALOG_SERVICE_NOT_ACTIVE]: () => (0, i18n_1.t)('errors.catalogServiceNotActive'),
|
|
143
|
-
[ERROR_TYPE.INTERNAL_SERVER_ERROR]: (error) => {
|
|
144
|
-
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
145
|
-
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
146
|
-
errorDesc: (0, i18n_1.t)('errors.internalServerError', { errorMsg })
|
|
147
|
-
});
|
|
148
|
-
},
|
|
149
|
-
[ERROR_TYPE.NOT_FOUND]: () => (0, i18n_1.t)('errors.urlNotFound'),
|
|
150
|
-
[ERROR_TYPE.ODATA_URL_NOT_FOUND]: () => (0, i18n_1.t)('errors.odataServiceUrlNotFound'),
|
|
151
|
-
[ERROR_TYPE.BAD_GATEWAY]: (error) => {
|
|
152
|
-
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
153
|
-
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
154
|
-
errorDesc: (0, i18n_1.t)('errors.badGateway', { errorMsg })
|
|
155
|
-
});
|
|
156
|
-
},
|
|
157
|
-
[ERROR_TYPE.DESTINATION_UNAVAILABLE]: () => (0, i18n_1.t)('errors.destination.unavailable'),
|
|
158
|
-
[ERROR_TYPE.DESTINATION_NOT_FOUND]: () => (0, i18n_1.t)('errors.destination.notFound'),
|
|
159
|
-
[ERROR_TYPE.DESTINATION_MISCONFIGURED]: (error) => (0, i18n_1.t)('errors.destination.misconfigured', {
|
|
160
|
-
destinationProperty: typeof error === 'string' ? error : JSON.stringify(error)
|
|
161
|
-
}),
|
|
162
|
-
[ERROR_TYPE.NO_V2_SERVICES]: () => (0, i18n_1.t)('errors.noServicesAvailable', { version: '2' }),
|
|
163
|
-
[ERROR_TYPE.NO_V4_SERVICES]: () => (0, i18n_1.t)('errors.noServicesAvailable', { version: '4' }),
|
|
164
|
-
[ERROR_TYPE.DESTINATION_BAD_GATEWAY_503]: () => (0, i18n_1.t)('errors.destination.unavailable'),
|
|
165
|
-
[ERROR_TYPE.REDIRECT]: () => (0, i18n_1.t)('errors.redirectError'),
|
|
166
|
-
[ERROR_TYPE.NO_SUCH_HOST]: () => (0, i18n_1.t)('errors.noSuchHostError'),
|
|
167
|
-
[ERROR_TYPE.NO_ABAP_ENVS]: () => (0, i18n_1.t)('errors.abapEnvsUnavailable'),
|
|
168
|
-
[ERROR_TYPE.BAD_REQUEST]: (error) => {
|
|
169
|
-
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
170
|
-
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
171
|
-
errorDesc: (0, i18n_1.t)('errors.badRequest', { errorMsg })
|
|
172
|
-
});
|
|
173
|
-
},
|
|
174
|
-
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: () => (0, i18n_1.t)('errors.systemConnectionValidationFailed'),
|
|
175
|
-
[ERROR_TYPE.SERVER_HTTP_ERROR]: (error) => (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
176
|
-
errorDesc: ErrorHandler.getMessageFromError(error)
|
|
177
|
-
})
|
|
178
|
-
};
|
|
179
|
-
/**
|
|
180
|
-
*
|
|
181
|
-
* @param errorType
|
|
182
|
-
* @param error can be any object that will get stringified and passed to the specific error message for the error type entry, e.g. where the error message is parameterized
|
|
183
|
-
* @returns an error message for the specified error type
|
|
184
|
-
*/
|
|
185
|
-
static _errorMsg = (errorType, error) => {
|
|
186
|
-
return ErrorHandler._errorTypeToMsg[errorType](error);
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* Get the Guided Answers (help) node for the specified error type.
|
|
190
|
-
*
|
|
191
|
-
* @param errorType The error type for which a help node (help content id) may be returned
|
|
192
|
-
* @returns The Guided Answers node for the specified error type
|
|
193
|
-
*/
|
|
194
|
-
static getHelpNode = (errorType) => {
|
|
195
|
-
const errorToHelp = {
|
|
196
|
-
[ERROR_TYPE.SERVICES_UNAVAILABLE]: (0, btp_utils_1.isAppStudio)()
|
|
197
|
-
? guided_answers_helper_1.HELP_NODES.BAS_CATALOG_SERVICES_REQUEST_FAILED
|
|
198
|
-
: undefined,
|
|
199
|
-
[ERROR_TYPE.CERT]: guided_answers_helper_1.HELP_NODES.CERTIFICATE_ERROR,
|
|
200
|
-
[ERROR_TYPE.CERT_SELF_SIGNED]: guided_answers_helper_1.HELP_NODES.CERTIFICATE_ERROR,
|
|
201
|
-
[ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: guided_answers_helper_1.HELP_NODES.CERTIFICATE_ERROR,
|
|
202
|
-
[ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: guided_answers_helper_1.HELP_NODES.CERTIFICATE_ERROR,
|
|
203
|
-
[ERROR_TYPE.DESTINATION_MISCONFIGURED]: guided_answers_helper_1.HELP_NODES.DESTINATION_MISCONFIGURED,
|
|
204
|
-
[ERROR_TYPE.DESTINATION_UNAVAILABLE]: guided_answers_helper_1.HELP_NODES.DESTINATION_UNAVAILABLE,
|
|
205
|
-
[ERROR_TYPE.DESTINATION_NOT_FOUND]: guided_answers_helper_1.HELP_NODES.DESTINATION_NOT_FOUND,
|
|
206
|
-
[ERROR_TYPE.BAD_GATEWAY]: guided_answers_helper_1.HELP_NODES.BAD_GATEWAY,
|
|
207
|
-
[ERROR_TYPE.DESTINATION_BAD_GATEWAY_503]: guided_answers_helper_1.HELP_NODES.DESTINATION_BAD_GATEWAY_503,
|
|
208
|
-
[ERROR_TYPE.NO_V4_SERVICES]: guided_answers_helper_1.HELP_NODES.NO_V4_SERVICES,
|
|
209
|
-
[ERROR_TYPE.AUTH]: undefined,
|
|
210
|
-
[ERROR_TYPE.AUTH_TIMEOUT]: undefined,
|
|
211
|
-
[ERROR_TYPE.REDIRECT]: undefined,
|
|
212
|
-
[ERROR_TYPE.CERT_EXPIRED]: undefined,
|
|
213
|
-
[ERROR_TYPE.UNKNOWN]: undefined,
|
|
214
|
-
[ERROR_TYPE.INVALID_URL]: undefined,
|
|
215
|
-
[ERROR_TYPE.CONNECTION]: undefined,
|
|
216
|
-
[ERROR_TYPE.SERVICE_UNAVAILABLE]: undefined,
|
|
217
|
-
[ERROR_TYPE.NO_ABAP_ENVS]: undefined,
|
|
218
|
-
[ERROR_TYPE.CATALOG_SERVICE_NOT_ACTIVE]: undefined,
|
|
219
|
-
[ERROR_TYPE.NO_SUCH_HOST]: undefined,
|
|
220
|
-
[ERROR_TYPE.NOT_FOUND]: undefined,
|
|
221
|
-
[ERROR_TYPE.ODATA_URL_NOT_FOUND]: undefined,
|
|
222
|
-
[ERROR_TYPE.INTERNAL_SERVER_ERROR]: undefined,
|
|
223
|
-
[ERROR_TYPE.NO_V2_SERVICES]: undefined,
|
|
224
|
-
[ERROR_TYPE.TIMEOUT]: undefined,
|
|
225
|
-
[ERROR_TYPE.BAD_REQUEST]: undefined,
|
|
226
|
-
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: guided_answers_helper_1.HELP_NODES.DESTINATION_CONNECTION_ERRORS,
|
|
227
|
-
[ERROR_TYPE.SERVER_HTTP_ERROR]: undefined
|
|
228
|
-
};
|
|
229
|
-
return errorToHelp[errorType];
|
|
230
|
-
};
|
|
231
|
-
/**
|
|
232
|
-
* Find an error property for mapping to a general error type from most to least significant.
|
|
233
|
-
*
|
|
234
|
-
* @param error any type of error or object that has an error code, status, name or message
|
|
235
|
-
* @returns a value that can be used to look up a general error type
|
|
236
|
-
*/
|
|
237
|
-
static findErrorValueForMapping = (error) => error.response?.data?.error?.code ||
|
|
238
|
-
error.response?.status ||
|
|
239
|
-
error.response?.data ||
|
|
240
|
-
error.code ||
|
|
241
|
-
(['TypeError', 'Error'].includes(error.name) ? error.message : error.name) || // For generic error types use the message otherwise the name is more relevant
|
|
242
|
-
error.message ||
|
|
243
|
-
error;
|
|
244
|
-
/**
|
|
245
|
-
* Create an instance of the ErrorHandler.
|
|
246
|
-
*
|
|
247
|
-
* @param logger the logger instance to use
|
|
248
|
-
* @param enableGuidedAnswers if true, the end user validation errors will include guided answers to provide help
|
|
249
|
-
*/
|
|
250
|
-
constructor(logger, enableGuidedAnswers = false) {
|
|
251
|
-
ErrorHandler._logger = logger ?? new logger_1.ToolsLogger({ logPrefix: '@sap-ux/odata-service-inquirer' });
|
|
252
|
-
ErrorHandler.guidedAnswersEnabled = enableGuidedAnswers;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Get Guided Answers (context help) enabled value.
|
|
256
|
-
*
|
|
257
|
-
* @returns true if Guided Answers is enabled
|
|
258
|
-
*/
|
|
259
|
-
static get guidedAnswersEnabled() {
|
|
260
|
-
return ErrorHandler._guidedAnswersEnabled;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Toggle Guided Answers (context help) for validation errors.
|
|
264
|
-
*/
|
|
265
|
-
static set guidedAnswersEnabled(value) {
|
|
266
|
-
ErrorHandler._guidedAnswersEnabled = value;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Set the logger to be used for error messages.
|
|
270
|
-
*
|
|
271
|
-
* @param logger the logger instance to use
|
|
272
|
-
*/
|
|
273
|
-
static set logger(logger) {
|
|
274
|
-
ErrorHandler._logger = logger;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Get the logger used for error messages.
|
|
278
|
-
*
|
|
279
|
-
* @returns the logger instance
|
|
280
|
-
*/
|
|
281
|
-
static get logger() {
|
|
282
|
-
return ErrorHandler._logger;
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Tests if the error is a general certificate error.
|
|
286
|
-
*
|
|
287
|
-
* @param status the error type
|
|
288
|
-
* @returns true if the error is a general certificate error
|
|
289
|
-
*/
|
|
290
|
-
static isCertError(status) {
|
|
291
|
-
return [
|
|
292
|
-
ERROR_TYPE.CERT,
|
|
293
|
-
ERROR_TYPE.CERT_EXPIRED,
|
|
294
|
-
ERROR_TYPE.CERT_SELF_SIGNED,
|
|
295
|
-
ERROR_TYPE.CERT_UKNOWN_OR_INVALID,
|
|
296
|
-
ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN
|
|
297
|
-
].includes(ErrorHandler.getErrorType(status));
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Get the error type for the specified error, mapping status code, error code, error name, error message to a few general error types.
|
|
301
|
-
*
|
|
302
|
-
* @param error the error, string or status code to get the type for
|
|
303
|
-
* @returns the error type
|
|
304
|
-
*/
|
|
305
|
-
static getErrorType(error) {
|
|
306
|
-
let errorValueToFind = error;
|
|
307
|
-
if (error instanceof Error) {
|
|
308
|
-
errorValueToFind = ErrorHandler.findErrorValueForMapping(error);
|
|
309
|
-
}
|
|
310
|
-
return Object.keys(ERROR_TYPE).find((errorCodeType) => {
|
|
311
|
-
return exports.ERROR_MAP[errorCodeType].find((exp) => exp.test(errorValueToFind.toString()));
|
|
312
|
-
}, {});
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Maps errors to a few generic types, log a detailed error.
|
|
316
|
-
*
|
|
317
|
-
* @param error If the error is a string this will be logged as is. Otherwise it will be mapped to a general error internally, possibly retained and logged.
|
|
318
|
-
* @param userMsg If provided this will be set as the userErrorMsg instead of an error to msg map
|
|
319
|
-
* this allows a message more relevant to the context of where the error was generated to be used.
|
|
320
|
-
* @param retainError Defaults to true to retain the error state.
|
|
321
|
-
* @returns A user-friendly message for display in-line
|
|
322
|
-
*/
|
|
323
|
-
logErrorMsgs(error, userMsg, retainError = true) {
|
|
324
|
-
let resolvedError = {
|
|
325
|
-
errorMsg: '',
|
|
326
|
-
errorType: ERROR_TYPE.UNKNOWN
|
|
327
|
-
};
|
|
328
|
-
// Overloaded to allow ERROR_TYPE for convenience
|
|
329
|
-
if (Object.values(ERROR_TYPE).includes(error)) {
|
|
330
|
-
const errorType = error;
|
|
331
|
-
resolvedError.errorMsg = ErrorHandler.getErrorMsgFromType(errorType) ?? errorType.toString();
|
|
332
|
-
resolvedError.errorType = errorType;
|
|
333
|
-
}
|
|
334
|
-
else if (typeof error === 'string') {
|
|
335
|
-
resolvedError.errorMsg = error;
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
resolvedError = ErrorHandler.mapErrorToMsg(error);
|
|
339
|
-
}
|
|
340
|
-
ErrorHandler._logger.error(userMsg ? `${userMsg} ${resolvedError.errorMsg}` : resolvedError.errorMsg);
|
|
341
|
-
if (retainError) {
|
|
342
|
-
this.currentErrorMsg = userMsg ?? resolvedError.errorMsg;
|
|
343
|
-
this.currentErrorType = resolvedError.errorType;
|
|
344
|
-
}
|
|
345
|
-
return resolvedError.errorMsg;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Maps an error to a user-friendly message. The specified error may by a string (e.g. error message), number (e.g. status code), Error, or Axios error.
|
|
349
|
-
*
|
|
350
|
-
* @param error The error to map
|
|
351
|
-
* @returns The mapped error message and error type
|
|
352
|
-
*/
|
|
353
|
-
static mapErrorToMsg(error) {
|
|
354
|
-
let errorType;
|
|
355
|
-
if (Object.values(ERROR_TYPE).includes(error)) {
|
|
356
|
-
errorType = error;
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
// Map error type using more to less specific information if available
|
|
360
|
-
errorType = ErrorHandler.getErrorType(this.findErrorValueForMapping(error)) ?? ERROR_TYPE.UNKNOWN;
|
|
361
|
-
}
|
|
362
|
-
return {
|
|
363
|
-
errorMsg: ErrorHandler._errorMsg(errorType, error),
|
|
364
|
-
errorType
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Used by validate functions to report in-line user friendly errors.
|
|
369
|
-
* Checks if there is an existing error.
|
|
370
|
-
*
|
|
371
|
-
* @param error optional, if provided get the end user message that it maps to, otherwise get the previous error message, if a boolean is passed it will be interpreted as `reset`.
|
|
372
|
-
* @param reset optional, resets the previous error state if true, if error is omitted reset may be passed as the first argument
|
|
373
|
-
* @param fallback optional, return the message of the specified ERROR_TYPE if no previous end user message and no error specified
|
|
374
|
-
* @returns The error message
|
|
375
|
-
*/
|
|
376
|
-
getErrorMsg(error, reset, fallback) {
|
|
377
|
-
let errorMsg;
|
|
378
|
-
if (error && typeof error !== 'boolean') {
|
|
379
|
-
errorMsg = ErrorHandler.mapErrorToMsg(error).errorMsg;
|
|
380
|
-
}
|
|
381
|
-
// Get previous error message
|
|
382
|
-
if (!errorMsg) {
|
|
383
|
-
errorMsg = this.currentErrorMsg ?? (fallback ? ErrorHandler.getErrorMsgFromType(fallback) : undefined);
|
|
384
|
-
}
|
|
385
|
-
if (error === true || reset) {
|
|
386
|
-
this.currentErrorMsg = null;
|
|
387
|
-
this.currentErrorType = null;
|
|
388
|
-
}
|
|
389
|
-
return errorMsg;
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Used by validate functions to report in-line user friendly errors messages with help links.
|
|
393
|
-
* If the error type is unknown, this will find a mapped error type and return the help (ValidationLink) if it exists.
|
|
394
|
-
* If an error is not provided the current error state will be used. This does not log the message to the console.
|
|
395
|
-
* If a system is provided, the error type may be refined to provide a more specific error message for the system which generatd the error.
|
|
396
|
-
*
|
|
397
|
-
* @param error optional, if provided get the help link message that it maps to, otherwise get the previously logged error message help link
|
|
398
|
-
* @param reset optional, resets the previous error state if true
|
|
399
|
-
* @param destination optional, if provided the destination may be used to determine a more relevant error message, specific to the system properties
|
|
400
|
-
* @returns An instance of @see {ValidationLink}
|
|
401
|
-
*/
|
|
402
|
-
getValidationErrorHelp(error, reset = false, destination) {
|
|
403
|
-
let errorHelp;
|
|
404
|
-
let resolvedErrorMsg;
|
|
405
|
-
let resolvedErrorType;
|
|
406
|
-
if (error) {
|
|
407
|
-
({ errorMsg: resolvedErrorMsg, errorType: resolvedErrorType } = ErrorHandler.mapErrorToMsg(error));
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
// Use the existing error if we have it
|
|
411
|
-
resolvedErrorMsg = this.currentErrorMsg ?? undefined;
|
|
412
|
-
if (this.currentErrorType) {
|
|
413
|
-
resolvedErrorType = this.currentErrorType;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
if (resolvedErrorType) {
|
|
417
|
-
// If the destination is provided, we can refine the error type and therefore the generated help message, to be more specific
|
|
418
|
-
if (destination) {
|
|
419
|
-
const { errorType: destErrorType, errorMsg: destErrorMsg } = ErrorHandler.getDestinationSpecificError(resolvedErrorType, destination);
|
|
420
|
-
resolvedErrorMsg = destErrorMsg ?? resolvedErrorMsg;
|
|
421
|
-
resolvedErrorType = destErrorType ?? resolvedErrorType;
|
|
422
|
-
}
|
|
423
|
-
if (resolvedErrorType) {
|
|
424
|
-
errorHelp = ErrorHandler.getHelpForError(resolvedErrorType, resolvedErrorMsg);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
if (reset) {
|
|
428
|
-
this.currentErrorMsg = null;
|
|
429
|
-
this.currentErrorType = null;
|
|
430
|
-
}
|
|
431
|
-
return errorHelp ?? resolvedErrorMsg; // We mau not have a help link, so return the resolvedend user message
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Get a more specific error type for the specified destination.
|
|
435
|
-
*
|
|
436
|
-
* @param errorType
|
|
437
|
-
* @param destination
|
|
438
|
-
* @returns
|
|
439
|
-
*/
|
|
440
|
-
static getDestinationSpecificError(errorType, destination) {
|
|
441
|
-
let destErrorType;
|
|
442
|
-
let destErrorMsg;
|
|
443
|
-
// Add more specific error types for destinations here
|
|
444
|
-
if (!(0, btp_utils_1.isHTML5DynamicConfigured)(destination)) {
|
|
445
|
-
destErrorType = ERROR_TYPE.DESTINATION_MISCONFIGURED;
|
|
446
|
-
destErrorMsg = this.getErrorMsgFromType(destErrorType, 'HTML5.DynamicDestination');
|
|
447
|
-
}
|
|
448
|
-
else if (errorType === ERROR_TYPE.SERVICE_UNAVAILABLE) {
|
|
449
|
-
if ((0, btp_utils_1.isOnPremiseDestination)(destination)) {
|
|
450
|
-
destErrorType = ERROR_TYPE.DESTINATION_BAD_GATEWAY_503; // Remap to specific gateway to allow GA link to be associated
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
destErrorType = ERROR_TYPE.DESTINATION_CONNECTION_ERROR; // General destination connection error, GA link to connection page
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
else if (errorType === ERROR_TYPE.NOT_FOUND) {
|
|
457
|
-
destErrorType = ERROR_TYPE.DESTINATION_NOT_FOUND;
|
|
458
|
-
}
|
|
459
|
-
else if (ERROR_TYPE.INTERNAL_SERVER_ERROR === errorType || ERROR_TYPE.SERVER_HTTP_ERROR === errorType) {
|
|
460
|
-
// We cannot tell in BAS what this means, so we will just say the connection failed
|
|
461
|
-
destErrorType = ERROR_TYPE.DESTINATION_CONNECTION_ERROR;
|
|
462
|
-
}
|
|
463
|
-
// Always raise a telemetry event for destination related errors
|
|
464
|
-
(0, utils_1.sendTelemetryEvent)(telemBasError, {
|
|
465
|
-
basErrorType: destErrorType ?? errorType,
|
|
466
|
-
destODataType: (0, utils_1.getTelemPropertyDestinationType)(destination)
|
|
467
|
-
});
|
|
468
|
-
return {
|
|
469
|
-
errorType: destErrorType ?? errorType,
|
|
470
|
-
errorMsg: destErrorMsg
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Get the error message for the specified error type.
|
|
475
|
-
*
|
|
476
|
-
* @param errorType The error type for which the message may be returned
|
|
477
|
-
* @param error optional, if provided may be used to get generate a more specific error message, or be included in the message
|
|
478
|
-
* @returns The error message for the specified error type
|
|
479
|
-
*/
|
|
480
|
-
static getErrorMsgFromType(errorType, error) {
|
|
481
|
-
if (ERROR_TYPE[errorType]) {
|
|
482
|
-
return ErrorHandler._errorMsg(ERROR_TYPE[errorType], error);
|
|
483
|
-
}
|
|
484
|
-
return undefined;
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Checks if there is an existing error.
|
|
488
|
-
*
|
|
489
|
-
* @param reset - resets the current error state
|
|
490
|
-
* @returns true if there is an existing error
|
|
491
|
-
*/
|
|
492
|
-
hasError(reset = false) {
|
|
493
|
-
const hasError = !!this.currentErrorMsg;
|
|
494
|
-
if (reset) {
|
|
495
|
-
this.currentErrorMsg = null;
|
|
496
|
-
this.currentErrorType = null;
|
|
497
|
-
}
|
|
498
|
-
return hasError;
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Sets the current error state.
|
|
502
|
-
*
|
|
503
|
-
* @param errorType - the error type
|
|
504
|
-
* @param error - the original error, if any
|
|
505
|
-
*/
|
|
506
|
-
setCurrentError(errorType, error) {
|
|
507
|
-
this.currentErrorMsg = ErrorHandler._errorMsg(ERROR_TYPE[errorType], error);
|
|
508
|
-
this.currentErrorType = errorType;
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Gets the current error type state.
|
|
512
|
-
*
|
|
513
|
-
* @param reset - resets the current error state
|
|
514
|
-
* @returns The current error type
|
|
515
|
-
*/
|
|
516
|
-
getCurrentErrorType(reset = false) {
|
|
517
|
-
const currentErrorType = this.currentErrorType;
|
|
518
|
-
if (reset) {
|
|
519
|
-
this.currentErrorMsg = null;
|
|
520
|
-
this.currentErrorType = null;
|
|
521
|
-
}
|
|
522
|
-
return currentErrorType;
|
|
523
|
-
}
|
|
524
|
-
/**
|
|
525
|
-
* Maps an error type to a validation link if help (Guided Answers topic) is available for the specified error.
|
|
526
|
-
* Otherwise the specified error message is returned. To retrieve the previous error state @see getValidationErrorHelp.
|
|
527
|
-
* Use this (getHelpForError) if the error type is known.
|
|
528
|
-
*
|
|
529
|
-
* @param errorType - the error type to be mapped to help link
|
|
530
|
-
* @param errorMsg - the message to appear with the help link
|
|
531
|
-
* @returns A validation help link or help link message
|
|
532
|
-
*/
|
|
533
|
-
static getHelpForError(errorType, errorMsg) {
|
|
534
|
-
const helpNode = ErrorHandler.getHelpNode(errorType);
|
|
535
|
-
const mappedErrorMsg = errorMsg ?? ErrorHandler.getErrorMsgFromType(errorType);
|
|
536
|
-
if (helpNode) {
|
|
537
|
-
const valLink = {
|
|
538
|
-
message: mappedErrorMsg ?? '',
|
|
539
|
-
link: {
|
|
540
|
-
text: (0, i18n_1.t)('guidedAnswers.validationErrorHelpText'),
|
|
541
|
-
icon: guided_answers_helper_1.GUIDED_ANSWERS_ICON,
|
|
542
|
-
url: (0, guided_answers_helper_1.getHelpUrl)(guided_answers_helper_1.HELP_TREE.FIORI_TOOLS, [helpNode])
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
if (this.guidedAnswersEnabled) {
|
|
546
|
-
valLink.link.command = {
|
|
547
|
-
id: guided_answers_helper_1.GUIDED_ANSWERS_LAUNCH_CMD_ID,
|
|
548
|
-
params: {
|
|
549
|
-
treeId: guided_answers_helper_1.HELP_TREE.FIORI_TOOLS,
|
|
550
|
-
nodeIdPath: [helpNode],
|
|
551
|
-
trigger: '@sap-ux/odata-service-inquirer'
|
|
552
|
-
}
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
// Report the GA link created event
|
|
556
|
-
(0, utils_1.sendTelemetryEvent)(telemEventGALinkCreated, {
|
|
557
|
-
errorType,
|
|
558
|
-
isGuidedAnswersEnabled: this.guidedAnswersEnabled,
|
|
559
|
-
nodeIdPath: `${helpNode}`
|
|
560
|
-
});
|
|
561
|
-
return new types_1.ValidationLink(valLink);
|
|
562
|
-
}
|
|
563
|
-
return mappedErrorMsg;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
exports.ErrorHandler = ErrorHandler;
|
|
567
|
-
//# sourceMappingURL=error-handler.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ServiceInstanceInfo } from '@sap/cf-tools';
|
|
2
|
-
import type { ListChoiceOptions } from 'inquirer';
|
|
3
|
-
/**
|
|
4
|
-
* Get the name sorted list of ABAP instance choices from an active CF login. If not logged in, an error message is logged.
|
|
5
|
-
*
|
|
6
|
-
* @returns The list of ABAP instance choices
|
|
7
|
-
*/
|
|
8
|
-
export declare function getABAPInstanceChoices(): Promise<ListChoiceOptions<ServiceInstanceInfo>[]>;
|
|
9
|
-
//# sourceMappingURL=cf-helper.d.ts.map
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getABAPInstanceChoices = getABAPInstanceChoices;
|
|
4
|
-
const cf_tools_1 = require("@sap/cf-tools");
|
|
5
|
-
const error_handler_1 = require("../../../../error-handler/error-handler");
|
|
6
|
-
const i18n_1 = require("../../../../i18n");
|
|
7
|
-
const prompt_helpers_1 = require("../../../prompt-helpers");
|
|
8
|
-
const AbapEnvType = {
|
|
9
|
-
ABAP: 'abap',
|
|
10
|
-
ABAP_TRIAL: 'abap-trial',
|
|
11
|
-
ABAP_CANARY: 'abap-canary',
|
|
12
|
-
ABAP_OEM: 'abap-oem',
|
|
13
|
-
ABAP_OEM_CANARY: 'abap-oem-canary',
|
|
14
|
-
ABAP_HAAS: 'abap-haas',
|
|
15
|
-
ABAP_STAGING: 'abap-staging',
|
|
16
|
-
ABAP_INTERNAL_STAGING: 'abap-internal-staging',
|
|
17
|
-
DESTINATION: 'destination'
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Get the name sorted list of ABAP instance choices from an active CF login. If not logged in, an error message is logged.
|
|
21
|
-
*
|
|
22
|
-
* @returns The list of ABAP instance choices
|
|
23
|
-
*/
|
|
24
|
-
async function getABAPInstanceChoices() {
|
|
25
|
-
const choices = [];
|
|
26
|
-
try {
|
|
27
|
-
const filteredInstances = [
|
|
28
|
-
AbapEnvType.ABAP,
|
|
29
|
-
AbapEnvType.ABAP_TRIAL,
|
|
30
|
-
AbapEnvType.ABAP_CANARY,
|
|
31
|
-
AbapEnvType.ABAP_OEM,
|
|
32
|
-
AbapEnvType.ABAP_OEM_CANARY,
|
|
33
|
-
AbapEnvType.ABAP_HAAS,
|
|
34
|
-
AbapEnvType.ABAP_STAGING,
|
|
35
|
-
AbapEnvType.ABAP_INTERNAL_STAGING
|
|
36
|
-
];
|
|
37
|
-
const serviceInstanceInfo = await (0, cf_tools_1.apiGetServicesInstancesFilteredByType)(filteredInstances);
|
|
38
|
-
if (serviceInstanceInfo.length > 0) {
|
|
39
|
-
serviceInstanceInfo.forEach((service) => {
|
|
40
|
-
choices.push({ name: service['label'], value: service });
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
// No envs found
|
|
45
|
-
prompt_helpers_1.errorHandler.logErrorMsgs(error_handler_1.ERROR_TYPE.NO_ABAP_ENVS, (0, i18n_1.t)('errors.noAbapEnvsInCFSpace'));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
// Cannot connect to CF
|
|
50
|
-
prompt_helpers_1.errorHandler.logErrorMsgs(error_handler_1.ERROR_TYPE.NO_ABAP_ENVS, (0, i18n_1.t)('errors.abapEnvsCFDiscoveryFailed'));
|
|
51
|
-
}
|
|
52
|
-
return choices.sort((a, b) => (a.name ? a.name.localeCompare(b.name ?? '') : 0));
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=cf-helper.js.map
|