Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion bin/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const branch = process.env.TESTOMATIO_BRANCH;
const debug = require('debug')('testomatio:check');
const { version } = require('../package.json');
const { TEST_ID_REGEX } = require('../src/updateIds/constants');
const { formatErrorMessage } = require('../src/lib/errorMessage');
console.log(chalk.cyan.bold(` 🤩 Tests checker by Testomat.io v${version}`));

process.env.isTestomatioCli = true;
Expand Down Expand Up @@ -245,7 +246,7 @@ program
console.log('\n✨ Pull completed successfully!');
}
} catch (error) {
console.error(' ✖️ Failed to pull files:', error.message);
console.error(' ✖️ Failed to pull files:', formatErrorMessage(error));
process.exit(1);
}
});
Expand Down
71 changes: 71 additions & 0 deletions src/lib/errorMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
function getResponse(error) {
Comment thread
DenysKuchma marked this conversation as resolved.
Outdated
return error && (error.response || error.res);
}

function getStatus(error) {
const response = getResponse(error);
return error?.statusCode || error?.status || response?.statusCode || response?.status;
}

function getStatusText(error) {
const response = getResponse(error);
return error?.statusMessage || error?.statusText || response?.statusMessage || response?.statusText;
}

function getBody(error) {
const response = getResponse(error);
return error?.body || error?.data || response?.body || response?.data;
}

function extractBodyMessage(body) {
if (!body) return '';
if (typeof body === 'string') {
const trimmed = body.trim();
if (!trimmed) return '';

try {
return extractBodyMessage(JSON.parse(trimmed)) || trimmed;
} catch {
return trimmed;
}
}

if (typeof body !== 'object') return String(body);
if (body.message) return String(body.message);
if (body.error) return typeof body.error === 'string' ? body.error : JSON.stringify(body.error);
if (body.errors) return Array.isArray(body.errors) ? body.errors.join(', ') : JSON.stringify(body.errors);
return '';
}

function formatStatusMessage(status, statusText) {
return statusText ? `${status} ${statusText}` : String(status);
}

function formatErrorMessage(error) {
if (!error) return 'Unknown error';
if (typeof error === 'string') return error.trim() || 'Unknown error';

const status = getStatus(error);
const statusText = getStatusText(error);
const bodyMessage = extractBodyMessage(getBody(error));

if (status) {
const statusMessage = formatStatusMessage(status, statusText);
const message =
Number(status) === 504 ? `Request timed out (${statusMessage})` : `Request failed (${statusMessage})`;
return bodyMessage ? `${message}: ${bodyMessage}` : message;
}

if (error.message) return error.message;

try {
const json = JSON.stringify(error);
return json && json !== '{}' ? json : String(error);
} catch {
return String(error);
}
}

module.exports = {
formatErrorMessage,
};
3 changes: 2 additions & 1 deletion src/pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const debug = require('debug')('testomatio:pull');
const { formatErrorMessage } = require('./lib/errorMessage');

class Pull {
constructor(reporter, workDir = '.', options = {}) {
Expand Down Expand Up @@ -81,7 +82,7 @@ class Pull {
return createdFiles;
}
} catch (error) {
console.error('Error pulling files:', error.message);
console.error('Error pulling files:', formatErrorMessage(error));
throw error;
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const debug = require('debug')('testomatio:ids');
const { request } = isHttps ? require('https') : require('http');
const path = require('path');
const fs = require('fs');
const { formatErrorMessage } = require('./lib/errorMessage');

class Reporter {
constructor(apiKey, framework, workDir) {
Expand Down Expand Up @@ -55,7 +56,17 @@ class Reporter {
debug('Files fetched from Testomat.io', message);
if (resp.statusCode !== 200) {
debug('Files fetch failed', resp.statusCode, resp.statusMessage, message);
rej(message);
const error = new Error(
formatErrorMessage({
statusCode: resp.statusCode,
statusMessage: resp.statusMessage,
body: message,
}),
);
error.statusCode = resp.statusCode;
error.statusMessage = resp.statusMessage;
error.body = message;
rej(error);
} else {
res(JSON.parse(message));
}
Expand Down
31 changes: 31 additions & 0 deletions tests/error_message_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { expect } = require('chai');
const { formatErrorMessage } = require('../src/lib/errorMessage');

describe('formatErrorMessage', () => {
it('should format 504 responses without a body', () => {
const message = formatErrorMessage({
statusCode: 504,
statusMessage: 'Gateway Timeout',
});

expect(message).to.equal('Request timed out (504 Gateway Timeout)');
});

it('should use server body message when response has a body', () => {
const message = formatErrorMessage({
statusCode: 500,
statusMessage: 'Internal Server Error',
body: JSON.stringify({ message: 'Export failed' }),
});

expect(message).to.equal('Request failed (500 Internal Server Error): Export failed');
});

it('should keep regular Error messages', () => {
expect(formatErrorMessage(new Error('Server error'))).to.equal('Server error');
});

it('should not return undefined for plain objects', () => {
expect(formatErrorMessage({ code: 'ECONNRESET' })).to.equal('{"code":"ECONNRESET"}');
});
});
Loading