@sap-ux/odata-service-inquirer 0.5.33 → 0.5.34

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.
@@ -14,6 +14,7 @@ export declare enum ERROR_TYPE {
14
14
  CERT_SELF_SIGNED_CERT_IN_CHAIN = "CERT_SELF_SIGNED_CERT_IN_CHAIN",
15
15
  UNKNOWN = "UNKNOWN",
16
16
  INVALID_URL = "INVALID_URL",
17
+ TIMEOUT = "TIMEOUT",
17
18
  CONNECTION = "CONNECTION",
18
19
  SERVICES_UNAVAILABLE = "SERVICES_UNAVAILABLE",// All services
19
20
  SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",// Specific service
@@ -32,7 +33,7 @@ export declare enum ERROR_TYPE {
32
33
  NO_V4_SERVICES = "NO_V4_SERVICES"
33
34
  }
34
35
  export declare const ERROR_MAP: Record<ERROR_TYPE, RegExp[]>;
35
- type ValidationLinkOrString = string | ValidationLink | undefined;
36
+ type ValidationLinkOrString = string | ValidationLink;
36
37
  /**
37
38
  * Maps errors to end-user messages using some basic root cause analysis based on regex matching.
38
39
  * This class will also log errors and provide help links for validation errors in some limited use cases.
@@ -138,7 +139,7 @@ export declare class ErrorHandler {
138
139
  * @param reset optional, resets the previous error state if true
139
140
  * @returns An instance of @see {ValidationLink}
140
141
  */
141
- getValidationErrorHelp(error?: any, reset?: boolean): ValidationLinkOrString;
142
+ getValidationErrorHelp(error?: any, reset?: boolean): ValidationLinkOrString | undefined;
142
143
  /**
143
144
  * Get the error message for the specified error type.
144
145
  *
@@ -177,7 +178,7 @@ export declare class ErrorHandler {
177
178
  * @param errorMsg - the message to appear with the help link
178
179
  * @returns A validation help link or help link message
179
180
  */
180
- static getHelpForError(errorType: ERROR_TYPE, errorMsg?: string): ValidationLinkOrString;
181
+ static getHelpForError(errorType: ERROR_TYPE, errorMsg?: string): ValidationLinkOrString | undefined;
181
182
  }
182
183
  export {};
183
184
  //# sourceMappingURL=error-handler.d.ts.map
@@ -23,6 +23,7 @@ var ERROR_TYPE;
23
23
  ERROR_TYPE["CERT_SELF_SIGNED_CERT_IN_CHAIN"] = "CERT_SELF_SIGNED_CERT_IN_CHAIN";
24
24
  ERROR_TYPE["UNKNOWN"] = "UNKNOWN";
25
25
  ERROR_TYPE["INVALID_URL"] = "INVALID_URL";
26
+ ERROR_TYPE["TIMEOUT"] = "TIMEOUT";
26
27
  ERROR_TYPE["CONNECTION"] = "CONNECTION";
27
28
  ERROR_TYPE["SERVICES_UNAVAILABLE"] = "SERVICES_UNAVAILABLE";
28
29
  ERROR_TYPE["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
@@ -50,6 +51,7 @@ exports.ERROR_MAP = {
50
51
  /Unable to retrieve SAP Business Accelerator Hub key/ // API Hub error msg
51
52
  ],
52
53
  [ERROR_TYPE.AUTH_TIMEOUT]: [/UAATimeoutError/],
54
+ [ERROR_TYPE.TIMEOUT]: [/Timeout/],
53
55
  [ERROR_TYPE.CERT]: [], // General cert error, unspecified root cause
54
56
  [ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: [
55
57
  /UNABLE_TO_GET_ISSUER_CERT/,
@@ -60,7 +62,7 @@ exports.ERROR_MAP = {
60
62
  [ERROR_TYPE.CERT_SELF_SIGNED]: [/DEPTH_ZERO_SELF_SIGNED_CERT/],
61
63
  [ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: [/SELF_SIGNED_CERT_IN_CHAIN/],
62
64
  [ERROR_TYPE.UNKNOWN]: [],
63
- [ERROR_TYPE.CONNECTION]: [/ENOTFOUND/, /ECONNRESET/, /ECONNREFUSED/],
65
+ [ERROR_TYPE.CONNECTION]: [/ENOTFOUND/, /ECONNRESET/, /ECONNREFUSED/, /ConnectionError/],
64
66
  [ERROR_TYPE.SERVICES_UNAVAILABLE]: [],
65
67
  [ERROR_TYPE.SERVICE_UNAVAILABLE]: [/503/],
66
68
  [ERROR_TYPE.INVALID_URL]: [/Invalid URL/, /ERR_INVALID_URL/],
@@ -111,6 +113,7 @@ class ErrorHandler {
111
113
  }),
112
114
  [ERROR_TYPE.AUTH]: (0, i18n_1.t)('errors.authenticationFailed', { error }),
113
115
  [ERROR_TYPE.AUTH_TIMEOUT]: (0, i18n_1.t)('errors.authenticationTimeout'),
116
+ [ERROR_TYPE.TIMEOUT]: (0, i18n_1.t)('errors.timeout, { error }'),
114
117
  [ERROR_TYPE.INVALID_URL]: (0, i18n_1.t)('errors.invalidUrl'),
115
118
  [ERROR_TYPE.CONNECTION]: (0, i18n_1.t)('errors.connectionError', {
116
119
  error: error?.message || JSON.stringify(error)
@@ -170,7 +173,8 @@ class ErrorHandler {
170
173
  [ERROR_TYPE.NOT_FOUND]: undefined,
171
174
  [ERROR_TYPE.ODATA_URL_NOT_FOUND]: undefined,
172
175
  [ERROR_TYPE.INTERNAL_SERVER_ERROR]: undefined,
173
- [ERROR_TYPE.NO_V2_SERVICES]: undefined
176
+ [ERROR_TYPE.NO_V2_SERVICES]: undefined,
177
+ [ERROR_TYPE.TIMEOUT]: undefined
174
178
  };
175
179
  return errorToHelp[errorType];
176
180
  };
@@ -18,6 +18,8 @@ const types_2 = require("./types");
18
18
  const questions_1 = require("../abap-on-prem/questions");
19
19
  const questions_2 = require("../abap-on-btp/questions");
20
20
  const logger_helper_1 = __importDefault(require("../../../logger-helper"));
21
+ const prompt_helpers_2 = require("../../../prompt-helpers");
22
+ const error_handler_1 = require("../../../../error-handler/error-handler");
21
23
  // New system choice value is a hard to guess string to avoid conflicts with existing system names or user named systems
22
24
  // since it will be used as a new system value in the system selection prompt.
23
25
  exports.newSystemChoiceValue = '!@£*&937newSystem*X~qy^';
@@ -233,6 +235,10 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
233
235
  if (!connectValidator.validatedUrl) {
234
236
  return false;
235
237
  }
238
+ // if no choices are available and an error is present, return the error message
239
+ if (serviceChoices.length === 0 && prompt_helpers_2.errorHandler.hasError()) {
240
+ return error_handler_1.ErrorHandler.getHelpForError(error_handler_1.ERROR_TYPE.SERVICES_UNAVAILABLE) ?? false;
241
+ }
236
242
  // Dont re-request the same service details
237
243
  if (service && previousService?.servicePath !== service.servicePath) {
238
244
  previousService = service;
@@ -254,6 +260,10 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
254
260
  throw new Error(result);
255
261
  }
256
262
  }
263
+ if (serviceChoices.length === 0 && prompt_helpers_2.errorHandler.hasError()) {
264
+ const noServicesError = error_handler_1.ErrorHandler.getHelpForError(error_handler_1.ERROR_TYPE.SERVICES_UNAVAILABLE).toString();
265
+ throw new Error(noServicesError);
266
+ }
257
267
  return false;
258
268
  },
259
269
  name: `${promptNamespace}:${cliServicePromptName}`
@@ -1,4 +1,4 @@
1
- import { ServiceType, type Annotations, type CatalogService, type V2CatalogService, type ServiceProvider } from '@sap-ux/axios-extension';
1
+ import { type CatalogService, ServiceType, V2CatalogService, type Annotations, type ServiceProvider } from '@sap-ux/axios-extension';
2
2
  import type { ListChoiceOptions } from 'inquirer';
3
3
  import type { ServiceAnswer } from './types';
4
4
  import type { ConnectionValidator } from '../../../connectionValidator';
@@ -9,6 +9,7 @@ const i18n_1 = require("../../../../i18n");
9
9
  const logger_helper_1 = __importDefault(require("../../../logger-helper"));
10
10
  const utils_1 = require("../../../../utils");
11
11
  const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
12
+ const prompt_helpers_1 = require("../../../prompt-helpers");
12
13
  // Service ids continaining these paths should not be offered as UI compatible services
13
14
  const nonUIServicePaths = ['/IWBEP/COMMON/'];
14
15
  /**
@@ -47,6 +48,18 @@ const createServiceChoices = (serviceInfos) => {
47
48
  });
48
49
  return choices.sort((a, b) => (a.name ? a.name.localeCompare(b.name ?? '') : 0));
49
50
  };
51
+ /**
52
+ * Logs the catalog reuest errors.
53
+ *
54
+ * @param requestErrors catalog request errors
55
+ */
56
+ function logErrorsForHelp(requestErrors) {
57
+ // Log the first error only
58
+ const catalogErrors = Object.values(requestErrors);
59
+ if (catalogErrors.length > 0) {
60
+ catalogErrors.forEach((error) => prompt_helpers_1.errorHandler.logErrorMsgs(error));
61
+ }
62
+ }
50
63
  /**
51
64
  * Get the service choices from the specified catalogs.
52
65
  *
@@ -54,18 +67,30 @@ const createServiceChoices = (serviceInfos) => {
54
67
  * @returns service choices based on the provided catalogs
55
68
  */
56
69
  async function getServiceChoices(catalogs) {
70
+ const requestErrors = {};
57
71
  const listServicesRequests = catalogs.map(async (catalog) => {
58
72
  try {
59
73
  return await catalog.listServices();
60
74
  }
61
75
  catch (error) {
62
- logger_helper_1.default.logger.error(`An error occurred requesting services from: ${catalog.entitySet}. Some services may not be listed.`);
76
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceCatalogRequest', {
77
+ catalogRequestUri: catalog.getUri(),
78
+ entitySet: catalog.entitySet,
79
+ error
80
+ }));
81
+ // Save any errors for processing later as we may show more useful message to the user
82
+ Object.assign(requestErrors, {
83
+ [catalog instanceof axios_extension_1.V2CatalogService ? axios_extension_1.ODataVersion.v2 : axios_extension_1.ODataVersion.v4]: error
84
+ });
63
85
  return [];
64
86
  }
65
87
  });
66
88
  const serviceInfos = await Promise.all(listServicesRequests);
67
89
  const flatServices = serviceInfos?.flat() ?? [];
68
90
  logger_helper_1.default.logger.debug(`Number of services available: ${flatServices.length}`);
91
+ if (flatServices.length === 0) {
92
+ logErrorsForHelp(requestErrors);
93
+ }
69
94
  return createServiceChoices(flatServices);
70
95
  }
71
96
  exports.getServiceChoices = getServiceChoices;
@@ -130,6 +130,7 @@
130
130
  "authenticationTimeout": "Authorization was not verified within the allowed time. Please ensure you have authenticated using the associated browser window.",
131
131
  "invalidUrl": "Not a valid URL",
132
132
  "connectionError": "A connection error occurred, please ensure the target host is available on the network: {{- error}}",
133
+ "timeout": "A connection timeout error occurred: {{- error}}",
133
134
  "serviceUnavailable": "Selected service is returning an error.",
134
135
  "catalogServiceNotActive": "Catalog service is not active",
135
136
  "internalServerError": "The URL you have provided cannot be accessed and is returning: '{{- error}}'. Please ensure that the URL is accessible externally.",
@@ -155,7 +156,8 @@
155
156
  "serviceTypeRequestError": "Error retrieving service type: {{- error}}",
156
157
  "noAbapEnvsInCFSpace": "No ABAP environments in CF space found.",
157
158
  "abapEnvsCFDiscoveryFailed": "Discovering ABAP Environments failed. Please ensure you are logged into Cloud Foundry (see https://docs.cloudfoundry.org/cf-cli/getting-started.html#login).",
158
- "abapServiceAuthenticationFailed": "ABAP environment authentication using UAA failed."
159
+ "abapServiceAuthenticationFailed": "ABAP environment authentication using UAA failed.",
160
+ "serviceCatalogRequest": "An error occurred requesting services from: {{- catalogRequestUri }} and entity set: {{entitySet}}. {{error}}"
159
161
  },
160
162
  "texts": {
161
163
  "anExpiredCert": "an expired",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sap-ux/odata-service-inquirer",
3
3
  "description": "Prompts module that can prompt users for inputs required for odata service writing",
4
- "version": "0.5.33",
4
+ "version": "0.5.34",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -30,8 +30,8 @@
30
30
  "@sap-ux/btp-utils": "0.15.2",
31
31
  "@sap-ux/guided-answers-helper": "0.0.2",
32
32
  "@sap-ux/telemetry": "0.5.26",
33
- "@sap-ux/inquirer-common": "0.4.6",
34
33
  "@sap-ux/logger": "0.6.0",
34
+ "@sap-ux/inquirer-common": "0.4.6",
35
35
  "@sap-ux/project-access": "1.27.0",
36
36
  "@sap-ux/project-input-validator": "0.3.3",
37
37
  "@sap-ux/store": "0.9.1"