const template = require("babel-template");
const {
tryTemplate,
catchConsole,
mergeOptions,
matchesFile,
} = require("./util");
module.exports = function (babel) {
let types = babel.types;
const visitor = {
AwaitExpression(path) {
if (this.opts && !typeof this.opts === "object") {
return console.error(
"[babel-plugin-await-add-trycatch]: options need to be an object."
);
}
if (path.findParent((p) => p.isTryStatement())) {
return false;
}
const options = mergeOptions(this.opts);
const filePath = this.filename || this.file.opts.filename || "unknown";
if (matchesFile(options.exclude, filePath)) {
return;
}
if (options.include.length && !matchesFile(options.include, filePath)) {
return;
}
let node = path.node;
const asyncPath = path.findParent(
(p) =>
p.node.async &&
(p.isFunctionDeclaration() ||
p.isArrowFunctionExpression() ||
p.isFunctionExpression() ||
p.isObjectMethod())
);
let asyncName = "";
let type = asyncPath.node.type;
switch (type) {
case "FunctionExpression":
case "ArrowFunctionExpression":
let identifier = asyncPath.getSibling("id");
asyncName = identifier && identifier.node ? identifier.node.name : "";
break;
case "FunctionDeclaration":
asyncName = (asyncPath.node.id && asyncPath.node.id.name) || "";
break;
case "ObjectMethod":
asyncName = asyncPath.node.key.name || "";
break;
}
let funcName =
asyncName || (node.argument.callee && node.argument.callee.name) || "";
const temp = template(tryTemplate);
let tempArgumentObj = {
CatchError: types.stringLiteral(
catchConsole(filePath, funcName, options.customLog)
),
};
let tryNode = temp(tempArgumentObj);
let info = asyncPath.node.body;
tryNode.block.body.push(...info.body);
info.body = [tryNode];
},
};
return {
name: "babel-plugin-await-add-trycatch",
visitor,
};
};