Include Win32 error codes in MXC process launch failures (#61227)

## Why

MXC launch errors omit the native Windows error code, while the SDK diagnostics can contain command, environment, and working-directory data.

## What changed

Extract the numeric error code from recognized `CreateProcessW` failures and append it to the launch error without exposing the remaining SDK diagnostics. Preserve the existing error message when no code can be extracted.

## Testing

Add unit tests for extracting the code without trailing diagnostics and rejecting nonnumeric codes and errors from other APIs.

GitOrigin-RevId: ddfa6635ab4fe9293ab4d31f9fcd7cfe563d4928
This commit is contained in:
zm-oai
2026-11-13 01:43:44 +00:00
committed by copyberry
parent a46f05e2e3
commit 818bde0995
2 changed files with 43 additions and 1 deletions
+23 -1
View File
@@ -33,8 +33,30 @@ pub(super) fn launch(request: &ExecutionRequest) -> Result<i32> {
let mut logger = Logger::new(Mode::Buffer);
let mut child = BaseContainerRunner::new()
.spawn(request, &mut logger, StdioMode::Inherit)
.map_err(|error| anyhow::anyhow!("{}", error.error_message))?;
.map_err(|error| match create_process_error(&error.extended_error) {
Some(code) => anyhow::anyhow!(
"{} (CreateProcessW, Win32 error {code})",
error.error_message
),
None => anyhow::anyhow!("{}", error.error_message),
})?;
// Do not publish the SDK diagnostic buffer: it may contain command or
// environment data. This wrapper emits only the resulting launch error.
child.wait().context("waiting for the MXC command")
}
// The SDK appends the working directory and other diagnostics to this field.
// Only the Windows error number is safe to copy into the command result.
fn create_process_error(detail: &str) -> Option<u32> {
let number = detail
.strip_prefix(
"CreateProcessW(PROC_THREAD_ATTRIBUTE_SECURITY_ENVIRONMENT) failed: WIN32_ERROR(",
)?
.split_once(')')?
.0;
number.parse().ok()
}
#[cfg(test)]
#[path = "native_tests.rs"]
mod tests;
+20
View File
@@ -0,0 +1,20 @@
#![cfg(test)]
use super::create_process_error;
#[test]
fn returns_only_the_native_create_process_error() {
let api = "CreateProcessW(PROC_THREAD_ATTRIBUTE_SECURITY_ENVIRONMENT) failed: ";
assert_eq!(
create_process_error(&format!("{api}WIN32_ERROR(5) (working directory: private)")),
Some(5)
);
assert_eq!(
create_process_error(&format!("{api}WIN32_ERROR(private)")),
None
);
assert_eq!(
create_process_error("another API failed: WIN32_ERROR(5)"),
None
);
}