fix: improve CLI error handling and user guidance

- Add Node.js >= 22 runtime version check before any imports
- Add EADDRINUSE error handlers for HTTP and WebSocket servers
- Fix misleading 'Couldn't parse Quartz configuration' error message
- Add actionable guidance to sync/upgrade/push failure messages
- Add --concurrency validation (must be >= 1)
This commit is contained in:
saberzero1
2026-05-24 17:09:56 +02:00
parent caa55037f7
commit 7f00400ad2
2 changed files with 48 additions and 5 deletions

View File

@@ -1,4 +1,12 @@
#!/usr/bin/env -S node --no-deprecation #!/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 yargs from "yargs"
import { hideBin } from "yargs/helpers" import { hideBin } from "yargs/helpers"
import { import {

View File

@@ -320,6 +320,11 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
* @param {*} argv arguments for `build` * @param {*} argv arguments for `build`
*/ */
export async function handleBuild(argv) { 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) { if (argv.serve) {
argv.watch = true argv.watch = true
} }
@@ -409,7 +414,9 @@ export async function handleBuild(argv) {
} }
const result = await ctx.rebuild().catch((err) => { 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))}`) console.log(`Reason: ${styleText("gray", err.message ?? String(err))}`)
process.exit(1) process.exit(1)
}) })
@@ -545,8 +552,26 @@ export async function handleBuild(argv) {
return serve() 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 <number>`,
)
process.exit(1)
}
throw err
})
server.listen(argv.port) server.listen(argv.port)
const wss = new WebSocketServer({ port: argv.wsPort }) 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 <number>`,
)
process.exit(1)
}
throw err
})
wss.on("connection", (ws) => connections.push(ws)) wss.on("connection", (ws) => connections.push(ws))
console.log( console.log(
styleText( styleText(
@@ -623,7 +648,10 @@ export async function handleUpgrade(argv) {
} }
if (!pullOk) { 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) await popContentFolder(contentFolder)
if (fs.existsSync(lockfileBackup)) fs.unlinkSync(lockfileBackup) if (fs.existsSync(lockfileBackup)) fs.unlinkSync(lockfileBackup)
return return
@@ -669,7 +697,10 @@ export async function handleUpgrade(argv) {
if (res.status === 0) { if (res.status === 0) {
console.log(styleText("green", "Dependencies updated!")) console.log(styleText("green", "Dependencies updated!"))
} else { } 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...") console.log("Restoring plugins from lockfile...")
@@ -738,7 +769,10 @@ export async function handleSync(argv) {
try { try {
gitPull(ORIGIN_NAME, QUARTZ_SOURCE_BRANCH) gitPull(ORIGIN_NAME, QUARTZ_SOURCE_BRANCH)
} catch { } 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) await popContentFolder(contentFolder)
return return
} }
@@ -753,7 +787,8 @@ export async function handleSync(argv) {
}) })
if (res.status !== 0) { if (res.status !== 0) {
console.log( 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 return
} }