Increase robustness (#447)

This commit is contained in:
George Berezhnoy 2018-09-07 19:51:40 +03:00 committed by GitHub
parent 7acf321454
commit 9ab437fe38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 117 additions and 123 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -104,66 +104,70 @@ export default class Paste extends Module {
* @param {string} tool
*/
private processTool = ([name, tool]) => {
const toolPasteConfig = tool.onPaste || {};
try {
const toolPasteConfig = tool.onPaste || {};
if (this.config.initialBlock === name && !toolPasteConfig.handler) {
_.log(
`«${name}» Tool must provide a paste handler.`,
'warn',
);
}
if (this.config.initialBlock === name && !toolPasteConfig.handler) {
_.log(
`«${name}» Tool must provide a paste handler.`,
'warn',
);
}
if (toolPasteConfig.handler && typeof toolPasteConfig.handler !== 'function') {
_.log(
`Paste handler for «${name}» Tool should be a function.`,
'warn',
);
} else {
const tags = toolPasteConfig.tags || [];
if (toolPasteConfig.handler && typeof toolPasteConfig.handler !== 'function') {
_.log(
`Paste handler for «${name}» Tool should be a function.`,
'warn',
);
} else {
const tags = toolPasteConfig.tags || [];
tags.forEach((tag) => {
if (this.toolsTags.hasOwnProperty(tag)) {
_.log(
`Paste handler for «${name}» Tool on «${tag}» tag is skipped ` +
`because it is already used by «${this.toolsTags[tag].tool}» Tool.`,
'warn',
);
return;
}
tags.forEach((tag) => {
if (this.toolsTags.hasOwnProperty(tag)) {
_.log(
`Paste handler for «${name}» Tool on «${tag}» tag is skipped ` +
`because it is already used by «${this.toolsTags[tag].tool}» Tool.`,
'warn',
);
return;
}
this.toolsTags[tag] = {
handler: toolPasteConfig.handler,
tool: name,
};
});
}
if (!toolPasteConfig.patternHandler || _.isEmpty(toolPasteConfig.patterns)) {
return;
}
if (typeof toolPasteConfig.patternHandler !== 'function') {
_.log(
`Pattern parser for "${name}" Tool should be a function.`,
'warn',
);
} else {
Object.entries(toolPasteConfig.patterns).forEach(([key, pattern]: [string, RegExp]) => {
/** Still need to validate pattern as it provided by user */
if (!(pattern instanceof RegExp)) {
_.log(
`Pattern ${pattern} for "${tool}" Tool is skipped because it should be a Regexp instance.`,
'warn',
);
}
this.toolsPatterns.push({
key,
pattern,
handler: toolPasteConfig.patternHandler,
tool: name,
this.toolsTags[tag] = {
handler: toolPasteConfig.handler,
tool: name,
};
});
});
}
if (!toolPasteConfig.patternHandler || _.isEmpty(toolPasteConfig.patterns)) {
return;
}
if (typeof toolPasteConfig.patternHandler !== 'function') {
_.log(
`Pattern parser for «${name}» Tool should be a function.`,
'warn',
);
} else {
Object.entries(toolPasteConfig.patterns).forEach(([key, pattern]: [string, RegExp]) => {
/** Still need to validate pattern as it provided by user */
if (!(pattern instanceof RegExp)) {
_.log(
`Pattern ${pattern} for «${name}» Tool is skipped because it should be a Regexp instance.`,
'warn',
);
}
this.toolsPatterns.push({
key,
pattern,
handler: toolPasteConfig.patternHandler,
tool: name,
});
});
}
} catch (e) {
_.log(`Paste handling for «${name}» Tool is not enabled because of an error `, 'warn', e);
}
}
@ -259,7 +263,7 @@ export default class Paste extends Module {
let insertedBlock;
if (BlockManager.currentBlock && BlockManager.currentBlock.isEmpty) {
BlockManager.replace(blockData.tool, blockData.data);
insertedBlock = BlockManager.replace(blockData.tool, blockData.data);
} else {
insertedBlock = BlockManager.insert(blockData.tool, blockData.data);
}

View file

@ -279,7 +279,8 @@ export default class Tools extends Module {
toolPreparationList.push({
function : toolClass.prepare,
data : {
toolName
toolName,
config: this.toolsSettings[toolName]
}
});
} else {

View file

@ -73,27 +73,7 @@ export default class Util {
*
* @return {Promise}
*/
public static sequence(chains: ChainData[], success = () => {}, fallback = () => {}): Promise<void> {
return new Promise((resolve) => {
/**
* pluck each element from queue
* First, send resolved Promise as previous value
* Each plugins "prepare" method returns a Promise, that's why
* reduce current element will not be able to continue while can't get
* a resolved Promise
*/
chains.reduce((previousValue, currentValue, iteration) => {
return previousValue
.then(() => waitNextBlock(currentValue, success, fallback))
.then(() => {
// finished
if (iteration === chains.length - 1) {
resolve();
}
});
}, Promise.resolve());
});
public static async sequence(chains: ChainData[], success = () => {}, fallback = () => {}): Promise<void> {
/**
* Decorator
*
@ -104,25 +84,30 @@ export default class Util {
*
* @return {Promise}
*/
function waitNextBlock(
async function waitNextBlock(
chainData: ChainData,
successCallback: (data: any) => void,
fallbackCallback: (data: any) => void,
): Promise<void> {
return new Promise((resolve) => {
chainData.function()
.then(() => {
successCallback(chainData.data || {});
})
.then(resolve)
.catch(() => {
fallbackCallback(chainData.data || {});
// anyway, go ahead even it falls
resolve();
});
});
try {
await chainData.function(chainData.data);
await successCallback(typeof chainData.data !== 'undefined' ? chainData.data : {});
} catch (e) {
fallbackCallback(typeof chainData.data !== 'undefined' ? chainData.data : {});
}
}
/**
* pluck each element from queue
* First, send resolved Promise as previous value
* Each plugins "prepare" method returns a Promise, that's why
* reduce current element will not be able to continue while can't get
* a resolved Promise
*/
return await chains.reduce(async (previousValue, currentValue) => {
await previousValue;
return waitNextBlock(currentValue, success, fallback);
}, Promise.resolve());
}
/**