vmm: return 404 for API requests against a non-created VM

The HTTP API mapped every ApiError to 500 Internal Server Error, so an
API client could not distinguish "the VM has not been created yet" from
a genuine server-side failure without parsing the error message text.

Derive the HTTP status code from the error itself in error_response():
errors whose root cause is VmError::VmNotCreated or VmMissingConfig are
now reported as 404 Not Found, regardless of which API action surfaced
them. The existing 400 (bad request) and 429 (too many requests)
mappings are preserved.

State-conflict errors such as VmNotRunning would ideally map to 409
Conflict, but micro_http's StatusCode has no Conflict variant, so they
remain 500 for now.

Fixes: #7774

Signed-off-by: Max Makarov <maxpain@linux.com>
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
This commit is contained in:
Max Makarov
2026-06-03 04:29:03 +00:00
committed by Rob Bradford
parent a89600aeba
commit d595856748
2 changed files with 38 additions and 24 deletions
+11 -11
View File
@@ -276,7 +276,7 @@ impl EndpointHandler for VmCreate {
.map_err(HttpError::SerdeJsonDeserialize)
{
Ok(config) => config,
Err(e) => return error_response(e, StatusCode::BadRequest),
Err(e) => return error_response(e),
};
if let Some(ref mut nets) = vm_config.net {
@@ -287,8 +287,8 @@ impl EndpointHandler for VmCreate {
// This call sets all FDs to null while doing the same logging as
// similar code paths.
for cfg in cfgs {
if let Err(e) = attach_fds_to_cfg(vec![], *cfg)
.map_err(|e| error_response(e, StatusCode::InternalServerError))
if let Err(e) =
attach_fds_to_cfg(vec![], *cfg).map_err(error_response)
{
return e;
}
@@ -300,7 +300,7 @@ impl EndpointHandler for VmCreate {
.map_err(HttpError::ApiError)
{
Ok(_) => Response::new(Version::Http11, StatusCode::NoContent),
Err(e) => error_response(e, StatusCode::InternalServerError),
Err(e) => error_response(e),
}
}
@@ -308,7 +308,7 @@ impl EndpointHandler for VmCreate {
}
}
_ => error_response(HttpError::BadRequest, StatusCode::BadRequest),
_ => error_response(HttpError::BadRequest),
}
}
}
@@ -570,9 +570,9 @@ impl EndpointHandler for VmInfo {
response.set_body(Body::new(info_serialized));
response
}
Err(e) => error_response(e, StatusCode::InternalServerError),
Err(e) => error_response(e),
},
_ => error_response(HttpError::BadRequest, StatusCode::BadRequest),
_ => error_response(HttpError::BadRequest),
}
}
}
@@ -599,10 +599,10 @@ impl EndpointHandler for VmmPing {
response.set_body(Body::new(info_serialized));
response
}
Err(e) => error_response(e, StatusCode::InternalServerError),
Err(e) => error_response(e),
},
_ => error_response(HttpError::BadRequest, StatusCode::BadRequest),
_ => error_response(HttpError::BadRequest),
}
}
}
@@ -624,10 +624,10 @@ impl EndpointHandler for VmmShutdown {
.map_err(HttpError::ApiError)
{
Ok(_) => Response::new(Version::Http11, StatusCode::OK),
Err(e) => error_response(e, StatusCode::InternalServerError),
Err(e) => error_response(e),
}
}
_ => error_response(HttpError::BadRequest, StatusCode::BadRequest),
_ => error_response(HttpError::BadRequest),
}
}
}