improve error handling while serving
1 files added
7 files modified
| New file |
| | |
| | | --- |
| | | title: "Building your Quartz" |
| | | --- |
| | |
| | | draft: true |
| | | --- |
| | | |
| | | - typography fixes |
| | | - parse tags in content |
| | | - breadcrumbs component |
| | | - filetree component |
| | |
| | | npx quartz create |
| | | ``` |
| | | |
| | | This will guide you through initializing your Quartz with content and previewing it locally. |
| | | This will guide you through initializing your Quartz with content. |
| | | |
| | | When you're ready, you can edit `quartz.config.ts` to customize and configure Quartz more. Read the [[configuration]] page for more information on what each field in the configuration does. |
| | | |
| | | Then, when you're ready, see how to [[build]] and [[hosting|host]] Quartz. |
| | | |
| | | ## 🔧 Features |
| | | |
| | | - [[full-text search|Full-text search]], [[graph view]], [[backlinks]], [[Latex]], [[syntax highlighting]], [[popover previews]], and many more right out of the box |
| | |
| | | port: number |
| | | } |
| | | |
| | | export default async function buildQuartz(argv: Argv, version: string) { |
| | | async function buildQuartz(argv: Argv, version: string) { |
| | | console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`)) |
| | | const perf = new PerfTimer() |
| | | const output = argv.output |
| | |
| | | if (!ignored(fp)) { |
| | | console.log(chalk.yellow(`Detected change in ${fp}, rebuilding...`)) |
| | | const fullPath = `${argv.directory}${path.sep}${fp}` as FilePath |
| | | if (action === "add" || action === "change") { |
| | | const [parsedContent] = await parseMarkdown( |
| | | cfg.plugins.transformers, |
| | | argv.directory, |
| | | [fullPath], |
| | | argv.verbose, |
| | | ) |
| | | contentMap.set(fullPath, parsedContent) |
| | | } else if (action === "unlink") { |
| | | contentMap.delete(fullPath) |
| | | |
| | | try { |
| | | if (action === "add" || action === "change") { |
| | | const [parsedContent] = await parseMarkdown( |
| | | cfg.plugins.transformers, |
| | | argv.directory, |
| | | [fullPath], |
| | | argv.verbose, |
| | | ) |
| | | contentMap.set(fullPath, parsedContent) |
| | | } else if (action === "unlink") { |
| | | contentMap.delete(fullPath) |
| | | } |
| | | |
| | | await rimraf(output) |
| | | const parsedFiles = [...contentMap.values()] |
| | | const filteredContent = filterContent(cfg.plugins.filters, parsedFiles, argv.verbose) |
| | | await emitContent(argv.directory, output, cfg, filteredContent, argv.serve, argv.verbose) |
| | | console.log(chalk.green(`Done rebuilding in ${perf.timeSince("rebuild")}`)) |
| | | } catch { |
| | | console.log(chalk.yellow(`Rebuild failed. Waiting on a change to fix the error...`)) |
| | | } |
| | | |
| | | await rimraf(output) |
| | | const parsedFiles = [...contentMap.values()] |
| | | const filteredContent = filterContent(cfg.plugins.filters, parsedFiles, argv.verbose) |
| | | await emitContent(argv.directory, output, cfg, filteredContent, argv.serve, argv.verbose) |
| | | console.log(chalk.green(`Done rebuilding in ${perf.timeSince("rebuild")}`)) |
| | | connections.forEach((conn) => conn.send("rebuild")) |
| | | } |
| | | } |
| | |
| | | console.log("hint: exit with ctrl+c") |
| | | } |
| | | } |
| | | |
| | | export default async (argv: Argv, version: string) => { |
| | | try { |
| | | await buildQuartz(argv, version) |
| | | } catch { |
| | | console.log(chalk.red("\nExiting Quartz due to a fatal error")) |
| | | process.exit(1) |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | success(text: string) { |
| | | end(text?: string) { |
| | | if (!this.verbose) { |
| | | this.spinner!.stop(true) |
| | | } |
| | | console.log(text) |
| | | if (text) { |
| | | console.log(text) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } catch (err) { |
| | | trace(`Failed to emit from plugin \`${emitter.name}\``, err as Error) |
| | | process.exit(1) |
| | | throw err |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | log.success(`Emitted ${emittedFiles} files to \`${output}\` in ${perf.timeSince()}`) |
| | | log.end(`Emitted ${emittedFiles} files to \`${output}\` in ${perf.timeSince()}`) |
| | | } |
| | |
| | | } |
| | | } catch (err) { |
| | | trace(`\nFailed to process \`${fp}\``, err as Error) |
| | | process.exit(1) |
| | | throw err |
| | | } |
| | | } |
| | | |
| | |
| | | let res: ProcessedContent[] = [] |
| | | log.start(`Parsing input files using ${concurrency} threads`) |
| | | if (concurrency === 1) { |
| | | const processor = createProcessor(transformers) |
| | | const parse = createFileParser(transformers, baseDir, fps, allSlugs, verbose) |
| | | res = await parse(processor) |
| | | try { |
| | | const processor = createProcessor(transformers) |
| | | const parse = createFileParser(transformers, baseDir, fps, allSlugs, verbose) |
| | | res = await parse(processor) |
| | | } catch (error) { |
| | | log.end() |
| | | throw error |
| | | } |
| | | } else { |
| | | await transpileWorkerScript() |
| | | const pool = workerpool.pool("./quartz/bootstrap-worker.mjs", { |
| | |
| | | await pool.terminate() |
| | | } |
| | | |
| | | log.success(`Parsed ${res.length} Markdown files in ${perf.timeSince()}`) |
| | | log.end(`Parsed ${res.length} Markdown files in ${perf.timeSince()}`) |
| | | return res |
| | | } |
| | |
| | | const stack = err.stack |
| | | console.log() |
| | | console.log( |
| | | chalk.bgRed.white.bold(" ERROR ") + |
| | | "\n" + |
| | | chalk.bgRed.black.bold(" ERROR ") + |
| | | "\n" + |
| | | chalk.red(` ${msg}`) + |
| | | (err.message.length > 0 ? `: ${err.message}` : ""), |
| | | ) |