Skip to content

Commit

Permalink
Merge pull request #56 from blendededge/error-handling
Browse files Browse the repository at this point in the history
Added outer catch to all actions
  • Loading branch information
winklerj committed Oct 24, 2023
2 parents f7fe0ce + ada0222 commit ee8dbcc
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 191 deletions.
123 changes: 67 additions & 56 deletions lib/actions/attachmentToJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,67 +31,78 @@ function checkFileName(self, fileName, pattern) {

// eslint-disable-next-line max-len, no-unused-vars
module.exports.process = async function processAction(msg, cfg, snapshot, headers, tokenData = {}) {
const self = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
const TOKEN = cfg.token ? cfg.token : tokenData.apiKey;
const { attachments } = msg;
const pattern = new RegExp(cfg !== undefined ? cfg.pattern || '(.xml)' : '(.xml)');
let foundXML = false;

self.logger.info('Attachment to XML started');
self.logger.info('Found %s attachments', Object.keys(attachments || {}).length);

const maxFileSize = cfg.maxFileSize ? cfg.maxFileSize : MAX_FILE_SIZE;

// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(attachments)) {
const attachment = attachments[key];
const fileName = key;
// get file size based attachment object may not be define or be accurate
let fileSize = attachment.size;
self.logger.info('Processing attachment');

if (checkFileName(self, fileName, pattern)) {
if (fileSize === undefined || fileSize < maxFileSize) {
// eslint-disable-next-line no-await-in-loop
const response = await new AttachmentProcessor(self, TOKEN, cfg.attachmentServiceUrl).getAttachment(attachment.url, 'arraybuffer');

self.logger.debug(`For provided filename response status: ${response.status}`);

self.logger.debug('the response is ', response);

if (response.status >= 400) {
throw new Error(`Error in making request to ${attachment.url}
Status code: ${response.status},
Body: ${Buffer.from(response.data, 'binary').toString('base64')}`);
}

const responseBodyString = Buffer.from(response.data, 'binary').toString('utf-8');

if (!responseBodyString) {
throw new Error(`Empty attachment received for file ${fileName}`);
}

fileSize = sizeof(responseBodyString);
if (fileSize < maxFileSize && cfg.splitResult) {
await xml2Json.process(self, responseBodyString, cfg);
self.logger.debug('Attachment to XML finished');
foundXML = true;
} else if (fileSize < maxFileSize) {
await xml2Json.process(self, responseBodyString, cfg);
self.logger.debug('Attachment to XML finished');
foundXML = true;
let self;
try {
self = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
const TOKEN = cfg.token ? cfg.token : tokenData.apiKey;
const { attachments } = msg;
const pattern = new RegExp(cfg !== undefined ? cfg.pattern || '(.xml)' : '(.xml)');
let foundXML = false;

self.logger.info('Attachment to XML started');
self.logger.info('Found %s attachments', Object.keys(attachments || {}).length);

const maxFileSize = cfg.maxFileSize ? cfg.maxFileSize : MAX_FILE_SIZE;

// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(attachments)) {
const attachment = attachments[key];
const fileName = key;
// get file size based attachment object may not be define or be accurate
let fileSize = attachment.size;
self.logger.info('Processing attachment');

if (checkFileName(self, fileName, pattern)) {
if (fileSize === undefined || fileSize < maxFileSize) {
// eslint-disable-next-line no-await-in-loop
const response = await new AttachmentProcessor(self, TOKEN, cfg.attachmentServiceUrl).getAttachment(attachment.url, 'arraybuffer');

self.logger.debug(`For provided filename response status: ${response.status}`);

self.logger.debug('the response is ', response);

if (response.status >= 400) {
throw new Error(`Error in making request to ${attachment.url}
Status code: ${response.status},
Body: ${Buffer.from(response.data, 'binary').toString('base64')}`);
}

const responseBodyString = Buffer.from(response.data, 'binary').toString('utf-8');

if (!responseBodyString) {
throw new Error(`Empty attachment received for file ${fileName}`);
}

fileSize = sizeof(responseBodyString);
if (fileSize < maxFileSize && cfg.splitResult) {
await xml2Json.process(self, responseBodyString, cfg);
self.logger.debug('Attachment to XML finished');
foundXML = true;
} else if (fileSize < maxFileSize) {
await xml2Json.process(self, responseBodyString, cfg);
self.logger.debug('Attachment to XML finished');
foundXML = true;
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${maxFileSize} byte, file given was: ${fileSize} byte.`);
}
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${maxFileSize} byte, file given was: ${fileSize} byte.`);
}
} else {
throw new Error(`Attachment ${key} is too large to be processed my XML component.`
+ ` File limit is: ${maxFileSize} byte, file given was: ${fileSize} byte.`);
}
}
if (!foundXML) {
self.logger.info('No XML files that match the pattern found within attachments');
}
self.emit('end');
} catch (e) {
if (self) {
self.logger.error('Error occurred while processing attachment to XML: ', JSON.stringify(e));
self.emit('error', e);
} else {
this.logger.error('Error occurred while processing attachment to XML attachmentToJson: ', JSON.stringify(e));
this.emit('error', e);
}
}
if (!foundXML) {
self.logger.info('No XML files that match the pattern found within attachments');
}
self.emit('end');
};
139 changes: 75 additions & 64 deletions lib/actions/jsonToXml.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,80 +9,91 @@ const MAX_FILE_SIZE = process.env.MAX_FILE_SIZE * MB_TO_BYTES || 10 * MB_TO_BYTE

// eslint-disable-next-line no-unused-vars
module.exports.process = async function process(msg, cfg, snapshot, headers, tokenData = {}) {
const wrapped = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
const TOKEN = cfg.token ? cfg.token : tokenData.apiKey;
const { input } = msg.data;
const {
uploadToAttachment, excludeXmlHeader, headerStandalone, renderOpts, cData, docType,
} = cfg;
let wrapped;
try {
wrapped = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
const TOKEN = cfg.token ? cfg.token : tokenData.apiKey;
const { input } = msg.data;
const {
uploadToAttachment, excludeXmlHeader, headerStandalone, renderOpts, cData, docType,
} = cfg;

wrapped.logger.info('Message received.');
wrapped.logger.info('Message received.');

const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
explicitRoot: false,
xmldec: {
standalone: headerStandalone,
encoding: 'UTF-8',
},
headless: excludeXmlHeader,
doctype: docType ? { pubID: docType } : null,
cdata: cData,
};
const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
explicitRoot: false,
xmldec: {
standalone: headerStandalone,
encoding: 'UTF-8',
},
headless: excludeXmlHeader,
doctype: docType ? { pubID: docType } : null,
cdata: cData,
};

if (renderOpts) {
options.renderOpts = renderOpts;
}
if (renderOpts) {
options.renderOpts = renderOpts;
}

const builder = new xml2js.Builder(options);
const builder = new xml2js.Builder(options);

// Check to make sure that input has at most one key
// https://github.com/Leonidas-from-XIV/node-xml2js/issues/564
if (!_.isPlainObject(input) || Object.keys(input).length !== 1) {
throw new Error('Input must be an object with exactly one key.');
}
// Check to make sure that input has at most one key
// https://github.com/Leonidas-from-XIV/node-xml2js/issues/564
if (!_.isPlainObject(input) || Object.keys(input).length !== 1) {
throw new Error('Input must be an object with exactly one key.');
}

const xmlString = builder.buildObject(input);
const xmlString = builder.buildObject(input);

if (!uploadToAttachment) {
wrapped.logger.info('Sending XML data in message.');
await wrapped.emit('data', messages.newMessage({
xmlString,
}));
return;
}
if (!uploadToAttachment) {
wrapped.logger.info('Sending XML data in message.');
await wrapped.emit('data', messages.newMessage({
xmlString,
}));
return;
}

const attachmentSize = Buffer.byteLength(xmlString);
if (attachmentSize > MAX_FILE_SIZE) {
throw new Error(`XML data is ${attachmentSize} bytes, and is too large to upload as an attachment. Max attachment size is ${MAX_FILE_SIZE} bytes`);
}
wrapped.logger.info(`Will create XML attachment of size ${attachmentSize} byte(s)`);
const attachmentSize = Buffer.byteLength(xmlString);
if (attachmentSize > MAX_FILE_SIZE) {
throw new Error(`XML data is ${attachmentSize} bytes, and is too large to upload as an attachment. Max attachment size is ${MAX_FILE_SIZE} bytes`);
}
wrapped.logger.info(`Will create XML attachment of size ${attachmentSize} byte(s)`);

const attachmentProcessor = new AttachmentProcessor(wrapped, TOKEN, cfg.attachmentServiceUrl);
const uploadResult = await attachmentProcessor.uploadAttachment(xmlString, 'application/xml');
const attachmentUrl = uploadResult.config.url;
wrapped.logger.info('Attachment created successfully');
const attachmentProcessor = new AttachmentProcessor(wrapped, TOKEN, cfg.attachmentServiceUrl);
const uploadResult = await attachmentProcessor.uploadAttachment(xmlString, 'application/xml');
const attachmentUrl = uploadResult.config.url;
wrapped.logger.info('Attachment created successfully');

const outboundMessage = messages.newMessage();
let filename = 'jsonToXml.xml';
if (cfg.filenameJsonata) {
filename = transform(msg, { customMapping: cfg.filenameJsonata });
wrapped.logger.info(`Transformed filename: ${filename}`);
}
const outboundMessage = messages.newMessage();
let filename = 'jsonToXml.xml';
if (cfg.filenameJsonata) {
filename = transform(msg, { customMapping: cfg.filenameJsonata });
wrapped.logger.info(`Transformed filename: ${filename}`);
}

outboundMessage.attachments[filename] = {
url: attachmentUrl,
size: attachmentSize,
};
outboundMessage.attachments[filename] = {
url: attachmentUrl,
size: attachmentSize,
};

outboundMessage.data = {
attachmentUrl,
attachmentSize,
};
await wrapped.emit('data', outboundMessage);
wrapped.emit('end');
outboundMessage.data = {
attachmentUrl,
attachmentSize,
};
await wrapped.emit('data', outboundMessage);
wrapped.emit('end');
} catch (e) {
if (wrapped) {
wrapped.logger.error('Error occurred: ', JSON.stringify(e));
wrapped.emit('error', e);
} else {
this.logger.error('Error occurred jsonToXml: ', JSON.stringify(e));
this.emit('error', e);
}
}
};
53 changes: 32 additions & 21 deletions lib/actions/jsonToXmlOld.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,41 @@ function validateJsonPropNames(value, key) {
*/
// eslint-disable-next-line no-unused-vars
async function processAction(msg, cfg, snapshot, headers, tokenData) {
const self = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
self.logger.debug('Action started...');
const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
tagNameProcessors: [
(name) => name.replace(':', '-'),
],
};
const builder = new xml2js.Builder(options);
let self;
try {
self = await wrapper(this, msg, cfg, snapshot, headers, tokenData);
self.logger.debug('Action started...');
const options = {
trim: false,
normalize: false,
explicitArray: false,
normalizeTags: false,
attrkey: '_attr',
tagNameProcessors: [
(name) => name.replace(':', '-'),
],
};
const builder = new xml2js.Builder(options);

const jsonToTransform = msg.data;
const jsonToTransform = msg.data;

validateJsonPropNames(jsonToTransform);
validateJsonPropNames(jsonToTransform);

const result = builder.buildObject(jsonToTransform);
self.logger.debug('Successfully converted body to XML');
self.emit('data', messages.newMessage({
xmlString: result,
}));
self.emit('end');
const result = builder.buildObject(jsonToTransform);
self.logger.debug('Successfully converted body to XML');
self.emit('data', messages.newMessage({
xmlString: result,
}));
self.emit('end');
} catch (e) {
if (self) {
self.logger.error('Error occurred: ', JSON.stringify(e));
self.emit('error', e);
} else {
this.logger.error('Error occurred jsonToXmlOld: ', JSON.stringify(e));
this.emit('error', e);
}
}
}

module.exports.process = processAction;
Loading

0 comments on commit ee8dbcc

Please sign in to comment.