mirror of
https://github.com/zadam/trilium.git
synced 2026-01-06 06:34:25 +01:00
feat(export/zip): improve error handling
This commit is contained in:
parent
b20a8bc90b
commit
294a2e6fdb
@ -515,97 +515,108 @@ ${markdownContent}`;
|
|||||||
archive.append(cssContent, { name: cssMeta.dataFileName });
|
archive.append(cssContent, { name: cssMeta.dataFileName });
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingFileNames: Record<string, number> = format === "html" ? { navigation: 0, index: 1 } : {};
|
try {
|
||||||
const rootMeta = createNoteMeta(branch, { notePath: [] }, existingFileNames);
|
const existingFileNames: Record<string, number> = format === "html" ? { navigation: 0, index: 1 } : {};
|
||||||
if (!rootMeta) {
|
const rootMeta = createNoteMeta(branch, { notePath: [] }, existingFileNames);
|
||||||
throw new Error("Unable to create root meta.");
|
if (!rootMeta) {
|
||||||
}
|
throw new Error("Unable to create root meta.");
|
||||||
|
}
|
||||||
|
|
||||||
const metaFile: NoteMetaFile = {
|
const metaFile: NoteMetaFile = {
|
||||||
formatVersion: 2,
|
formatVersion: 2,
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
files: [rootMeta]
|
files: [rootMeta]
|
||||||
};
|
|
||||||
|
|
||||||
let navigationMeta: NoteMeta | null = null;
|
|
||||||
let indexMeta: NoteMeta | null = null;
|
|
||||||
let cssMeta: NoteMeta | null = null;
|
|
||||||
|
|
||||||
if (format === "html") {
|
|
||||||
navigationMeta = {
|
|
||||||
noImport: true,
|
|
||||||
dataFileName: "navigation.html"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
metaFile.files.push(navigationMeta);
|
let navigationMeta: NoteMeta | null = null;
|
||||||
|
let indexMeta: NoteMeta | null = null;
|
||||||
|
let cssMeta: NoteMeta | null = null;
|
||||||
|
|
||||||
indexMeta = {
|
if (format === "html") {
|
||||||
noImport: true,
|
navigationMeta = {
|
||||||
dataFileName: "index.html"
|
noImport: true,
|
||||||
};
|
dataFileName: "navigation.html"
|
||||||
|
};
|
||||||
|
|
||||||
metaFile.files.push(indexMeta);
|
metaFile.files.push(navigationMeta);
|
||||||
|
|
||||||
cssMeta = {
|
indexMeta = {
|
||||||
noImport: true,
|
noImport: true,
|
||||||
dataFileName: "style.css"
|
dataFileName: "index.html"
|
||||||
};
|
};
|
||||||
|
|
||||||
metaFile.files.push(cssMeta);
|
metaFile.files.push(indexMeta);
|
||||||
}
|
|
||||||
|
|
||||||
for (const noteMeta of Object.values(noteIdToMeta)) {
|
cssMeta = {
|
||||||
// filter out relations which are not inside this export
|
noImport: true,
|
||||||
noteMeta.attributes = (noteMeta.attributes || []).filter((attr) => {
|
dataFileName: "style.css"
|
||||||
if (attr.type !== "relation") {
|
};
|
||||||
return true;
|
|
||||||
} else if (attr.value in noteIdToMeta) {
|
metaFile.files.push(cssMeta);
|
||||||
return true;
|
}
|
||||||
} else if (attr.value === "root" || attr.value?.startsWith("_")) {
|
|
||||||
// relations to "named" noteIds can be preserved
|
for (const noteMeta of Object.values(noteIdToMeta)) {
|
||||||
return true;
|
// filter out relations which are not inside this export
|
||||||
} else {
|
noteMeta.attributes = (noteMeta.attributes || []).filter((attr) => {
|
||||||
return false;
|
if (attr.type !== "relation") {
|
||||||
|
return true;
|
||||||
|
} else if (attr.value in noteIdToMeta) {
|
||||||
|
return true;
|
||||||
|
} else if (attr.value === "root" || attr.value?.startsWith("_")) {
|
||||||
|
// relations to "named" noteIds can be preserved
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rootMeta) {
|
||||||
|
// corner case of disabled export for exported note
|
||||||
|
if ("sendStatus" in res) {
|
||||||
|
res.sendStatus(400);
|
||||||
}
|
}
|
||||||
});
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const metaFileJson = JSON.stringify(metaFile, null, "\t");
|
||||||
|
|
||||||
|
archive.append(metaFileJson, { name: "!!!meta.json" });
|
||||||
|
|
||||||
|
saveNote(rootMeta, "");
|
||||||
|
|
||||||
|
if (format === "html") {
|
||||||
|
if (!navigationMeta || !indexMeta || !cssMeta) {
|
||||||
|
throw new Error("Missing meta.");
|
||||||
|
}
|
||||||
|
|
||||||
|
saveNavigation(rootMeta, navigationMeta);
|
||||||
|
saveIndex(rootMeta, indexMeta);
|
||||||
|
saveCss(rootMeta, cssMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
const note = branch.getNote();
|
||||||
|
const zipFileName = `${branch.prefix ? `${branch.prefix} - ` : ""}${note.getTitleOrProtected()}.zip`;
|
||||||
|
|
||||||
|
if (setHeaders && "setHeader" in res) {
|
||||||
|
res.setHeader("Content-Disposition", getContentDisposition(zipFileName));
|
||||||
|
res.setHeader("Content-Type", "application/zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
archive.pipe(res);
|
||||||
|
await archive.finalize();
|
||||||
|
taskContext.taskSucceeded();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const message = `Export failed with error: ${e instanceof Error ? e.message : String(e)}`;
|
||||||
|
log.error(message);
|
||||||
|
taskContext.reportError(message);
|
||||||
|
|
||||||
if (!rootMeta) {
|
|
||||||
// corner case of disabled export for exported note
|
|
||||||
if ("sendStatus" in res) {
|
if ("sendStatus" in res) {
|
||||||
res.sendStatus(400);
|
res.removeHeader("Content-Disposition");
|
||||||
|
res.removeHeader("Content-Type");
|
||||||
|
res.status(500).send(message);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const metaFileJson = JSON.stringify(metaFile, null, "\t");
|
|
||||||
|
|
||||||
archive.append(metaFileJson, { name: "!!!meta.json" });
|
|
||||||
|
|
||||||
saveNote(rootMeta, "");
|
|
||||||
|
|
||||||
if (format === "html") {
|
|
||||||
if (!navigationMeta || !indexMeta || !cssMeta) {
|
|
||||||
throw new Error("Missing meta.");
|
|
||||||
}
|
|
||||||
|
|
||||||
saveNavigation(rootMeta, navigationMeta);
|
|
||||||
saveIndex(rootMeta, indexMeta);
|
|
||||||
saveCss(rootMeta, cssMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
const note = branch.getNote();
|
|
||||||
const zipFileName = `${branch.prefix ? `${branch.prefix} - ` : ""}${note.getTitleOrProtected()}.zip`;
|
|
||||||
|
|
||||||
if (setHeaders && "setHeader" in res) {
|
|
||||||
res.setHeader("Content-Disposition", getContentDisposition(zipFileName));
|
|
||||||
res.setHeader("Content-Type", "application/zip");
|
|
||||||
}
|
|
||||||
|
|
||||||
archive.pipe(res);
|
|
||||||
await archive.finalize();
|
|
||||||
|
|
||||||
taskContext.taskSucceeded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exportToZipFile(noteId: string, format: "markdown" | "html", zipFilePath: string, zipExportOptions?: AdvancedExportOptions) {
|
async function exportToZipFile(noteId: string, format: "markdown" | "html", zipFilePath: string, zipExportOptions?: AdvancedExportOptions) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user