Fix compile error propagation: 'failure' instead of HTTP 500
Build and Deploy Verso / deploy (push) Successful in 10m37s
Build and Deploy Verso / deploy (push) Successful in 10m37s
LocalCommandRunner: attach captured stdout to the error object when exit code is 1, so callers can read Quarto's output even on failure. QuartoRunner: stop propagating plain 'exited' errors from Quarto up to CompileManager. A Quarto exit-code-1 is a compile failure, not a server error — CLSI already detects failure by the absence of output.pdf and returns status='failure' (HTTP 200). Previously it fell through to the generic error handler (HTTP 500), which caused the frontend to show "Server Error" instead of the log panel. Only true process-level errors (terminated, timedout) are propagated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,9 +89,10 @@ export default CommandRunner = {
|
||||
err.terminated = true
|
||||
return callback(err)
|
||||
} else if (code === 1) {
|
||||
// exit status from chktex
|
||||
// exit status from chktex (and any compiler that exits 1 on failure)
|
||||
err = new Error('exited')
|
||||
err.code = code
|
||||
err.stdout = stdout // preserve captured output for callers
|
||||
return callback(err)
|
||||
} else {
|
||||
return callback(null, { stdout, exitCode: code })
|
||||
|
||||
@@ -11,7 +11,10 @@ function runQuarto(compileName, options, callback) {
|
||||
const { directory, mainFile, image, environment, compileGroup } = options
|
||||
const timeout = options.timeout || 60000
|
||||
|
||||
logger.debug({ directory, timeout, mainFile, compileGroup }, 'starting quarto compile')
|
||||
logger.debug(
|
||||
{ directory, timeout, mainFile, compileGroup },
|
||||
'starting quarto compile'
|
||||
)
|
||||
|
||||
const command = _buildQuartoCommand(mainFile)
|
||||
|
||||
@@ -26,22 +29,31 @@ function runQuarto(compileName, options, callback) {
|
||||
null,
|
||||
function (error, output) {
|
||||
delete ProcessTable[compileName]
|
||||
if (error) {
|
||||
// Still try to write whatever output we captured before the error
|
||||
_writeLogOutput(compileName, directory, output, () => callback(error))
|
||||
return
|
||||
|
||||
// Propagate real process-level errors (killed, timed out) but NOT
|
||||
// ordinary non-zero exit codes from Quarto itself. A Quarto compile
|
||||
// failure (exit code 1) is not a server error — the absence of
|
||||
// output.pdf is sufficient for CompileController to return 'failure'.
|
||||
if (error && (error.terminated || error.timedout)) {
|
||||
return callback(error)
|
||||
}
|
||||
_writeLogOutput(compileName, directory, output, () => callback(null, output))
|
||||
|
||||
// On exit-code-1 errors LocalCommandRunner attaches stdout to the
|
||||
// error object; merge it so _writeLogOutput can persist it.
|
||||
const combined = output || (error ? { stdout: error.stdout || '' } : null)
|
||||
_writeLogOutput(compileName, directory, combined, () =>
|
||||
callback(null, combined)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function _buildQuartoCommand(mainFile) {
|
||||
// Run through a POSIX shell so we can merge stderr into stdout.
|
||||
// Run through a POSIX shell so stderr is merged into stdout (2>&1).
|
||||
// Quarto writes all progress and error messages to stderr; without this
|
||||
// merge the UI would show nothing in the log panel on failure.
|
||||
// LocalCommandRunner replaces $COMPILE_DIR before the shell sees the string,
|
||||
// so the substitution is safe and no shell variable expansion occurs.
|
||||
// the log panel would be empty on failure.
|
||||
// LocalCommandRunner replaces $COMPILE_DIR before the shell sees the
|
||||
// string, so no shell variable expansion occurs for that token.
|
||||
const quartoArgs = [
|
||||
'quarto',
|
||||
'render',
|
||||
|
||||
Reference in New Issue
Block a user