diff --git a/.changeset/many-eyes-call.md b/.changeset/many-eyes-call.md new file mode 100644 index 0000000000..75e3be47d3 --- /dev/null +++ b/.changeset/many-eyes-call.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Improves error logs when executing commands diff --git a/benchmark/bench/cli-startup.js b/benchmark/bench/cli-startup.js index 6f25554997..2e9eccf645 100644 --- a/benchmark/bench/cli-startup.js +++ b/benchmark/bench/cli-startup.js @@ -45,7 +45,7 @@ async function benchmarkCommand(command, args, root) { for (let i = 0; i < 10; i++) { const start = performance.now(); - await exec(command, args, { nodeOptions: { cwd: root } }); + await exec(command, args, { nodeOptions: { cwd: root }, throwOnError: true }); durations.push(performance.now() - start); } diff --git a/benchmark/bench/memory.js b/benchmark/bench/memory.js index f1846204f8..9a3f94bc73 100644 --- a/benchmark/bench/memory.js +++ b/benchmark/bench/memory.js @@ -26,6 +26,7 @@ export async function run(projectDir, outputFile) { ASTRO_TIMER_PATH: outputFilePath, }, }, + throwOnError: true, }); console.log('Raw results written to', outputFilePath); diff --git a/benchmark/bench/render.js b/benchmark/bench/render.js index aee04f2b5b..8dfd47fbbe 100644 --- a/benchmark/bench/render.js +++ b/benchmark/bench/render.js @@ -25,6 +25,7 @@ export async function run(projectDir, outputFile) { cwd: root, stdio: 'inherit', }, + throwOnError: true, }); console.log('Previewing...'); @@ -33,6 +34,7 @@ export async function run(projectDir, outputFile) { cwd: root, stdio: 'inherit', }, + throwOnError: true, }); console.log('Waiting for server ready...'); diff --git a/benchmark/bench/server-stress.js b/benchmark/bench/server-stress.js index 18b31c71c5..9e93c4cd93 100644 --- a/benchmark/bench/server-stress.js +++ b/benchmark/bench/server-stress.js @@ -24,6 +24,7 @@ export async function run(projectDir, outputFile) { cwd: root, stdio: 'inherit', }, + throwOnError: true, }); console.log('Previewing...'); diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index 869a867d1c..08c57dc044 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -10,7 +10,6 @@ import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; import maxSatisfying from 'semver/ranges/max-satisfying.js'; -import { exec } from 'tinyexec'; import { loadTSConfig, resolveConfig, @@ -30,6 +29,7 @@ import { appendForwardSlash } from '../../core/path.js'; import { apply as applyPolyfill } from '../../core/polyfill.js'; import { ensureProcessNodeEnv, parseNpmName } from '../../core/util.js'; import { eventCliSession, telemetry } from '../../events/index.js'; +import { exec } from '../exec.js'; import { type Flags, createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js'; import { fetchPackageJson, fetchPackageVersions } from '../install-package.js'; diff --git a/packages/astro/src/cli/docs/open.ts b/packages/astro/src/cli/docs/open.ts index 6f2fe4c821..5b59e6c471 100644 --- a/packages/astro/src/cli/docs/open.ts +++ b/packages/astro/src/cli/docs/open.ts @@ -1,4 +1,5 @@ -import { type Result, exec } from 'tinyexec'; +import type { Result } from 'tinyexec'; +import { exec } from '../exec.js'; /** * Credit: Azhar22 diff --git a/packages/astro/src/cli/exec.ts b/packages/astro/src/cli/exec.ts new file mode 100644 index 0000000000..b2af3c377e --- /dev/null +++ b/packages/astro/src/cli/exec.ts @@ -0,0 +1,26 @@ +import { NonZeroExitError, type Options, x } from 'tinyexec'; + +/** + * Improve tinyexec error logging and set `throwOnError` to `true` by default + */ +export function exec(command: string, args?: string[], options?: Partial) { + return x(command, args, { + throwOnError: true, + ...options, + }).then( + (o) => o, + (e) => { + if (e instanceof NonZeroExitError) { + const fullCommand = args?.length + ? `${command} ${args.map((a) => (a.includes(' ') ? `"${a}"` : a)).join(' ')}` + : command; + const message = `The command \`${fullCommand}\` exited with code ${e.exitCode}`; + const newError = new Error(message, e.cause ? { cause: e.cause } : undefined); + (newError as any).stderr = e.output?.stderr; + (newError as any).stdout = e.output?.stdout; + throw newError; + } + throw e; + }, + ); +} diff --git a/packages/astro/src/cli/install-package.ts b/packages/astro/src/cli/install-package.ts index 2bd3afc8f0..25bd5c445a 100644 --- a/packages/astro/src/cli/install-package.ts +++ b/packages/astro/src/cli/install-package.ts @@ -5,9 +5,9 @@ import { bold, cyan, dim, magenta } from 'kleur/colors'; import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; -import { exec } from 'tinyexec'; import whichPm from 'which-pm'; import type { Logger } from '../core/logger/core.js'; +import { exec } from './exec.js'; const require = createRequire(import.meta.url); diff --git a/scripts/smoke/cleanup.js b/scripts/smoke/cleanup.js index 1bb398d9e1..e901556ec7 100644 --- a/scripts/smoke/cleanup.js +++ b/scripts/smoke/cleanup.js @@ -38,6 +38,7 @@ async function run() { await exec('pnpm', ['install'], { nodeOptions: { cwd: fileURLToPath(rootDir), stdio: ['pipe', 'inherit', 'inherit'] }, + throwOnError: true }); } diff --git a/scripts/smoke/index.js b/scripts/smoke/index.js index 49887cd2ee..1d9651c598 100644 --- a/scripts/smoke/index.js +++ b/scripts/smoke/index.js @@ -33,7 +33,10 @@ async function run() { const directories = [...(await getChildDirectories(smokeDir)), ...(await getChildDirectories(exampleDir))]; /** @type {Partial} */ - const execOptions = { nodeOptions: { cwd: fileURLToPath(rootDir), stdio: 'inherit' }}; + const execOptions = { + nodeOptions: { cwd: fileURLToPath(rootDir), stdio: 'inherit' }, + throwOnError: true, + }; console.log('🤖', 'Preparing', 'pnpm');