Skip to content

Commit

Permalink
Add traits.expandToOne.onError to be able to ignore an error
Browse files Browse the repository at this point in the history
  • Loading branch information
edi9999 committed Jan 9, 2025
1 parent 6faf1a1 commit ca7c831
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 2 deletions.
118 changes: 118 additions & 0 deletions es6/tests/e2e/traits.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
const { expect, makeDocxV4 } = require("../utils.js");
const Docxtemplater = require("../../docxtemplater.js");
const { traits, isContent } = Docxtemplater.DocUtils;
const { XTTemplateError } = Docxtemplater.Errors;

describe("Traits", () => {
it("should work with expandToOne and call onError if multiple tags in same paragraph", () => {
const moduleName = "foo_module/foo";
const ignoredErrors = [];
const module = {
name: "FooModule",
requiredAPIVersion: "3.0.0",
matchers() {
return [["__", moduleName]];
},
postparse(parsed) {
parsed = traits.expandToOne(parsed, {
moduleName,
getInner: ({ part, left, right, postparsed, index }) => {
const paragraphParts = postparsed.slice(left + 1, right);
let error = false;
for (let i = 0, len = paragraphParts.length; i < len; i++) {
const p = paragraphParts[i];
if (i === index - left - 1) {
continue;
}
if (isContent(p)) {
error = true;
}
}
if (error === true) {
// This error wil be catched by onError and then ignored (and put into ignoredErrs)
const err = new XTTemplateError(
"Foo tag should be the only text in a paragraph"
);
throw err;
}
return part;
},
expandTo: "w:p",
onError(opts) {
const { part } = opts;
ignoredErrors.push(
`${opts.rootError.name} ${opts.rootError.message}`
);
if (part.module === moduleName) {
return "ignore";
}
},
});
return parsed;
},
render(part) {
if (part.module === moduleName) {
return {
value: "MYVAL",
};
}
},
};
const doc = makeDocxV4("<w:p><w:t>Foo {__user} {__bar}</w:t></w:p>", {
modules: [module],
}).render();

expect(ignoredErrors).to.deep.equal([
"TemplateError Foo tag should be the only text in a paragraph",
]);
expect(doc.getFullText()).to.be.equal("Foo MYVAL MYVAL");
});

it("should work with expandToOne and call onError if no surrounding paragraphs found", () => {
const moduleName = "foo_module/foo";
const ignoredErrors = [];
const module = {
name: "FooModule",
requiredAPIVersion: "3.0.0",
matchers() {
return [["__", moduleName]];
},
postparse(parsed) {
parsed = traits.expandToOne(parsed, {
moduleName,
expandTo: "w:p",
onError(opts) {
const { part } = opts;
ignoredErrors.push(
`${opts.name || opts.rootError.name} ${opts.message || opts.rootError.message}`
);
if (part.module === moduleName) {
return "ignore";
}
},
error: {
message: "FooModule tag should be the only text in a paragraph",
id: "foo_tag_w_p_noexpand",
},
});
return parsed;
},
render(part) {
if (part.module === moduleName) {
return {
value: "MYVAL",
};
}
},
};
const doc = makeDocxV4("<w:t>Foo {__user} {__bar}</w:t></w:p>", {
modules: [module],
}).render();

expect(ignoredErrors).to.deep.equal([
"TemplateError FooModule tag should be the only text in a paragraph",
"TemplateError FooModule tag should be the only text in a paragraph",
]);
expect(doc.getFullText()).to.be.equal("Foo MYVAL MYVAL");
});
});
1 change: 1 addition & 0 deletions es6/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ function startTest() {
require("./e2e/integration.js");
require("./e2e/doc-props.js");
require("./e2e/modules.js");
require("./e2e/traits.js");
require("./e2e/pptx.js");
require("./e2e/table.js");
require("./e2e/async.js");
Expand Down
23 changes: 21 additions & 2 deletions es6/traits.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,21 @@ function getExpandLimit(part, index, postparsed, options) {
right = getRight(postparsed, expandTo, index);
} catch (rootError) {
if (rootError instanceof XTTemplateError) {
throwExpandNotFound({
const errProps = {
part,
rootError,
postparsed,
expandTo,
index,
...options.error,
});
};
if (options.onError) {
const errorResult = options.onError(errProps);
if (errorResult === "ignore") {
return;
}
}
throwExpandNotFound(errProps);
}
throw rootError;
}
Expand Down Expand Up @@ -306,6 +313,18 @@ function expandToOne(postparsed, options) {
options
);
} catch (error) {
if (options.onError) {
const errorResult = options.onError({
part: limit.part,
rootError: error,
postparsed,
expandOne,
...options.errors,
});
if (errorResult === "ignore") {
continue;
}
}
if (error instanceof XTTemplateError) {
errors.push(error);
} else {
Expand Down

0 comments on commit ca7c831

Please sign in to comment.