Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions packages/contentstack-import/src/import/modules/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,11 @@ export default class EntriesImport extends BaseClass {
);

const onSuccess = ({ response: contentType, apiData: { uid } }: any) => {
log.success(`${uid} content type references removed temporarily`, this.importConfig.context);
log.debug(`Successfully processed content type: ${uid}`, this.importConfig.context);
log.success(`'${uid}' content type references removed temporarily`, this.importConfig.context);
log.debug(`Successfully processed content type: '${uid}'`, this.importConfig.context);
};
const onReject = ({ error, apiData: { uid } }: any) => {
handleAndLogError(error, { ...this.importConfig.context, uid }, `${uid} content type references removal failed`);
handleAndLogError(error, { ...this.importConfig.context, uid }, `'${uid}' content type references removal failed`);
};
return await this.makeConcurrentCall({
processName: 'Update content types (removing mandatory references temporarily)',
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-utilities/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/cli-utilities",
"version": "1.14.1",
"version": "1.14.2",
"description": "Utilities for contentstack projects",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
23 changes: 16 additions & 7 deletions packages/contentstack-utilities/src/authentication-handler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cliux as ux, authHandler, configHandler } from './index';
import { cliux as ux, authHandler, configHandler, formatError } from './index';

class AuthenticationHandler {
private authType: string;
Expand Down Expand Up @@ -33,7 +33,8 @@ class AuthenticationHandler {
break;
}
} catch (error) {
ux.print(`Error occurred while fetching auth details: ${error?.message}`, {
const formattedError = formatError(error);
ux.print(`Error occurred while fetching auth details: ${formattedError}`, {
color: 'red',
});
throw error;
Expand Down Expand Up @@ -75,7 +76,9 @@ class AuthenticationHandler {
if (refreshed) {
return this.refreshAccessToken(error, maxRetryCount); // Retry after refreshing the token
}
console.log('API(401) case error:-', error.response);

const errorDetails = formatError(error);
ux.print(`Authentication failed: ${errorDetails}`, { color: 'red' });
// For Basic Auth, exit immediately without retrying
return;
}
Expand All @@ -84,9 +87,11 @@ class AuthenticationHandler {
case 429:
case 408:
if (maxRetryCount >= 3) {
ux.print(`Max retry count reached, please login to proceed, status code: ${error.response.status}`, {
color: 'yellow',
});
const errorDetails = formatError(error);
const statusText = error?.response?.status === 429 ? 'Rate Limited' : 'Request Timeout';
ux.print(`Max retry attempts exceeded (${maxRetryCount}/3)`, { color: 'red' });
ux.print(`Status: ${error?.response?.status} - ${statusText}`, { color: 'yellow' });
ux.print(`Error: ${errorDetails}`, { color: 'white' });
return;
}
maxRetryCount++; // Increment for the next retry attempt
Expand All @@ -106,6 +111,8 @@ class AuthenticationHandler {
ux.print('Session timed out, please login to proceed', {
color: 'yellow',
});
ux.print('\nTo fix this:', { color: 'cyan' });
ux.print('• Run: "csdx auth:login"', { color: 'white' });
resolve(false);
} else if (this.authType === 'OAUTH') {
authHandler.host = hostName;
Expand All @@ -117,7 +124,9 @@ class AuthenticationHandler {
resolve(true);
})
.catch((error: any) => {
console.log(error);
const errorDetails = formatError(error);
ux.print('OAuth Token Refresh Failed', { color: 'red' });
ux.print(`Error: ${errorDetails}`, { color: 'white' });
resolve(false);
});
} else {
Expand Down
57 changes: 30 additions & 27 deletions packages/contentstack-utilities/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ export const formatError = function (error: any) {
parsedError = error;
}

// Helper function to append error details
const appendErrorDetails = (message: string, errorObj: any): string => {
if (errorObj.errors && typeof errorObj.errors === 'object' && Object.keys(errorObj.errors).length > 0) {
const entityNames: { [key: string]: string } = {
authorization: 'Authentication',
api_key: 'Stack API key',
uid: 'Content Type',
access_token: 'Delivery Token',
};

const errorList = Object.entries(errorObj.errors)
.map(([field, errors]) => {
const errorArray = Array.isArray(errors) ? errors : [errors];
const fieldName = entityNames[field] || field;
return ` • ${fieldName}: ${errorArray.join(', ')}`;
})
.join('\n');

return `${message}\n\nError Details:\n${errorList}\n`;
}
return message;
};

if (parsedError && typeof parsedError === 'object' && Object.keys(parsedError).length === 0) {
if (
!parsedError.message &&
Expand All @@ -121,25 +144,25 @@ export const formatError = function (error: any) {
}

if (parsedError?.response?.data?.errorMessage) {
return parsedError.response.data.errorMessage;
return appendErrorDetails(parsedError.response.data.errorMessage, parsedError?.response?.data || parsedError);
}

if (parsedError?.errorMessage) {
return parsedError.errorMessage;
return appendErrorDetails(parsedError.errorMessage, parsedError);
}

const status = parsedError?.status || parsedError?.response?.status;
const errorCode = parsedError?.errorCode || parsedError?.response?.data?.errorCode;
if (status === 422 && errorCode === 104) {
return 'Invalid email or password. Please check your credentials and try again.';
return appendErrorDetails('Invalid email or password. Please check your credentials and try again.', parsedError);
}

if (status === 401) {
return 'Authentication failed. Please check your credentials.';
return appendErrorDetails('Authentication failed. Please check your credentials.', parsedError);
}

if (status === 403) {
return 'Access denied. Please check your permissions.';
return appendErrorDetails('Access denied. Please check your permissions.', parsedError);
}

// Check for specific SSL error
Expand Down Expand Up @@ -174,28 +197,8 @@ export const formatError = function (error: any) {
// message is not in JSON format, no need to parse
}

// Append detailed error information if available
if (parsedError.errors && typeof parsedError.errors === 'object' && Object.keys(parsedError.errors).length > 0) {
const entityNames: { [key: string]: string } = {
authorization: 'Authentication',
api_key: 'Stack API key',
uid: 'Content Type',
// deepcode ignore HardcodedNonCryptoSecret: The hardcoded value 'access_token' is used as a key in an error message mapping object and does not represent a sensitive secret or cryptographic key.
access_token: 'Delivery Token',
};

const errorList = Object.entries(parsedError.errors)
.map(([field, errors]) => {
const errorArray = Array.isArray(errors) ? errors : [errors];
const fieldName = entityNames[field] || field;
return ` • ${fieldName}: ${errorArray.join(', ')}`;
})
.join('\n');

message += `\n\nAPI Errors:\n${errorList}`;
}

return message;
// Always append error details at the end
return appendErrorDetails(message, parsedError);
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@ export default class CLIErrorHandler {
* Extracts a clear, concise error message from various error types.
*/
private extractClearMessage(error: Error & Record<string, any>): string {
if (error?.response?.data?.errorMessage) {
return error.response.data.errorMessage;
}

if (error?.errorMessage) {
return error.errorMessage;
}

// Use existing formatError function for other cases
try {
const formattedMessage = formatError(error);
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@contentstack/cli-config": "~1.15.2",
"@contentstack/cli-launch": "^1.9.2",
"@contentstack/cli-migration": "~1.8.1",
"@contentstack/cli-utilities": "~1.14.1",
"@contentstack/cli-utilities": "~1.14.2",
"@contentstack/cli-variants": "~1.3.1",
"@contentstack/management": "~1.22.0",
"@oclif/core": "^4.3.0",
Expand Down
38 changes: 1 addition & 37 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading