|
@@ -54,6 +54,10 @@ const configSchema = {
|
|
|
type: 'number', title: 'Max Retry Delay (ms)', default: 30000,
|
|
type: 'number', title: 'Max Retry Delay (ms)', default: 30000,
|
|
|
description: 'Upper bound for the backoff'
|
|
description: 'Upper bound for the backoff'
|
|
|
},
|
|
},
|
|
|
|
|
+ skipOnError: {
|
|
|
|
|
+ type: 'boolean', title: 'Skip On Error', default: false,
|
|
|
|
|
+ description: 'Return success false and no items instead of failing the workflow. For a workflow reading several feeds, this is what lets the others carry on when one is unreachable - without it the first bad feed ends the run'
|
|
|
|
|
+ },
|
|
|
detectNewItems: {
|
|
detectNewItems: {
|
|
|
type: 'boolean',
|
|
type: 'boolean',
|
|
|
title: 'Detect New Items',
|
|
title: 'Detect New Items',
|
|
@@ -101,6 +105,8 @@ const inputSchema = {
|
|
|
const outputSchema = {
|
|
const outputSchema = {
|
|
|
type: 'object',
|
|
type: 'object',
|
|
|
properties: {
|
|
properties: {
|
|
|
|
|
+ success: { type: 'boolean', description: 'False when the feed could not be read and Skip On Error let the run carry on' },
|
|
|
|
|
+ error: { type: 'string', description: 'Why it could not be read, when it could not' },
|
|
|
feedTitle: { type: 'string', description: 'Title of the feed' },
|
|
feedTitle: { type: 'string', description: 'Title of the feed' },
|
|
|
feedLink: { type: 'string', description: 'Link to the feed homepage' },
|
|
feedLink: { type: 'string', description: 'Link to the feed homepage' },
|
|
|
feedDescription: { type: 'string', description: 'Description of the feed' },
|
|
feedDescription: { type: 'string', description: 'Description of the feed' },
|
|
@@ -699,7 +705,7 @@ function filterNewItems(items, seenIds) {
|
|
|
return newItems;
|
|
return newItems;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-async function execute(config, input) {
|
|
|
|
|
|
|
+async function readFeed(config, input) {
|
|
|
var url = input.url || config.url;
|
|
var url = input.url || config.url;
|
|
|
var filterKeyword = input.filterKeyword || config.filterKeyword;
|
|
var filterKeyword = input.filterKeyword || config.filterKeyword;
|
|
|
var filterNewerThan = input.filterNewerThan || config.filterNewerThan;
|
|
var filterNewerThan = input.filterNewerThan || config.filterNewerThan;
|
|
@@ -863,4 +869,33 @@ async function execute(config, input) {
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+async function execute(config, input) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var result = await readFeed(config, input);
|
|
|
|
|
+ result.success = true;
|
|
|
|
|
+ result.error = '';
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ if (config.skipOnError !== true) {
|
|
|
|
|
+ throw err;
|
|
|
|
|
+ }
|
|
|
|
|
+ var message = (err && err.message) ? err.message : String(err);
|
|
|
|
|
+ smartbotic.log.warn('RSS Reader: ' + (config.url || '') + ' could not be read, skipping: ' + message);
|
|
|
|
|
+ // Shaped like a successful read with nothing in it, so a merge or a
|
|
|
|
|
+ // loop downstream does not have to know the difference - and carrying
|
|
|
|
|
+ // the reason means a run that produced nothing can still say why.
|
|
|
|
|
+ return {
|
|
|
|
|
+ success: false,
|
|
|
|
|
+ error: message,
|
|
|
|
|
+ feedTitle: '',
|
|
|
|
|
+ feedLink: '',
|
|
|
|
|
+ feedDescription: '',
|
|
|
|
|
+ itemCount: 0,
|
|
|
|
|
+ items: [],
|
|
|
|
|
+ newItemCount: 0,
|
|
|
|
|
+ totalFeedItemCount: 0
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
module.exports = { configSchema, inputSchema, outputSchema, execute };
|
|
module.exports = { configSchema, inputSchema, outputSchema, execute };
|