diff --git a/quartz/bootstrap-cli.mjs b/quartz/bootstrap-cli.mjs index 151a604..99332ba 100755 --- a/quartz/bootstrap-cli.mjs +++ b/quartz/bootstrap-cli.mjs @@ -1,4 +1,12 @@ #!/usr/bin/env -S node --no-deprecation +const [major] = process.versions.node.split(".").map(Number) +if (major < 22) { + console.error( + `\nQuartz requires Node.js >= 22, but you are running Node.js ${process.version}.\n` + + `Please upgrade: https://nodejs.org/\n`, + ) + process.exit(1) +} import yargs from "yargs" import { hideBin } from "yargs/helpers" import { diff --git a/quartz/cli/handlers.js b/quartz/cli/handlers.js index 24e9080..084014e 100644 --- a/quartz/cli/handlers.js +++ b/quartz/cli/handlers.js @@ -320,6 +320,11 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started. * @param {*} argv arguments for `build` */ export async function handleBuild(argv) { + if (argv.concurrency !== undefined && argv.concurrency < 1) { + console.error("Concurrency must be at least 1") + process.exit(1) + } + if (argv.serve) { argv.watch = true } @@ -409,7 +414,9 @@ export async function handleBuild(argv) { } const result = await ctx.rebuild().catch((err) => { - console.error(`${styleText("red", "Couldn't parse Quartz configuration:")} ${fp}`) + console.error( + `${styleText("red", "Failed to build Quartz.")} Check for syntax errors in your configuration or plugins.`, + ) console.log(`Reason: ${styleText("gray", err.message ?? String(err))}`) process.exit(1) }) @@ -545,8 +552,26 @@ export async function handleBuild(argv) { return serve() }) + server.on("error", (err) => { + if (err.code === "EADDRINUSE") { + console.error( + `Port ${argv.port} is already in use. Try a different port with --port `, + ) + process.exit(1) + } + throw err + }) server.listen(argv.port) const wss = new WebSocketServer({ port: argv.wsPort }) + wss.on("error", (err) => { + if (err.code === "EADDRINUSE") { + console.error( + `WebSocket port ${argv.wsPort} is already in use. Try a different port with --wsPort `, + ) + process.exit(1) + } + throw err + }) wss.on("connection", (ws) => connections.push(ws)) console.log( styleText( @@ -623,7 +648,10 @@ export async function handleUpgrade(argv) { } if (!pullOk) { - console.log(styleText("red", "An error occurred above while pulling updates.")) + console.log( + styleText("red", "An error occurred while pulling updates.") + + "\nCheck your network connection and git credentials. If you see merge conflicts, resolve them manually and run `npx quartz sync --no-pull`.", + ) await popContentFolder(contentFolder) if (fs.existsSync(lockfileBackup)) fs.unlinkSync(lockfileBackup) return @@ -669,7 +697,10 @@ export async function handleUpgrade(argv) { if (res.status === 0) { console.log(styleText("green", "Dependencies updated!")) } else { - console.log(styleText("red", "An error occurred above while installing dependencies.")) + console.log( + styleText("red", "An error occurred while installing dependencies.") + + "\nTry running `npm install` manually to see detailed errors.", + ) } console.log("Restoring plugins from lockfile...") @@ -738,7 +769,10 @@ export async function handleSync(argv) { try { gitPull(ORIGIN_NAME, QUARTZ_SOURCE_BRANCH) } catch { - console.log(styleText("red", "An error occurred above while pulling updates.")) + console.log( + styleText("red", "An error occurred while pulling updates from your repository.") + + "\nCheck your network connection and git credentials.", + ) await popContentFolder(contentFolder) return } @@ -753,7 +787,8 @@ export async function handleSync(argv) { }) if (res.status !== 0) { console.log( - styleText("red", `An error occurred above while pushing to remote ${ORIGIN_NAME}.`), + styleText("red", `An error occurred while pushing to remote ${ORIGIN_NAME}.`) + + "\nCheck that you have push access to the remote repository.", ) return }