timeout limits the code with the given timeout in seconds, and 'json-error' return json to stdout when the call returns an error like this:
{ "msg": "error message", "error": true, "code": <HTTP_STATUS_CODE>, // if it was an http error } with both options set, a client can more easily determine if the call ran into a timeout (since it will return a 503 error), and can poll it again both is done behind new parameters, so that we can stay backwards-compatible Signed-off-by: Dominik Csapak <d.csa...@proxmox.com> --- proxmox-file-restore/src/main.rs | 53 ++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/proxmox-file-restore/src/main.rs b/proxmox-file-restore/src/main.rs index cbf79802..16c197a9 100644 --- a/proxmox-file-restore/src/main.rs +++ b/proxmox-file-restore/src/main.rs @@ -7,6 +7,7 @@ use anyhow::{bail, format_err, Error}; use serde_json::{json, Value}; use proxmox_sys::fs::{create_path, CreateOptions}; +use proxmox_router::{http_err, HttpError}; use proxmox_router::cli::{ complete_file_name, default_table_format_options, format_and_print_result_full, get_output_format, @@ -213,6 +214,18 @@ async fn list_files( schema: OUTPUT_FORMAT, optional: true, }, + "json-error": { + type: Boolean, + description: "If set, errors are returned as json instead of writing to stderr", + optional: true, + default: false, + }, + "timeout": { + type: Integer, + description: "Defines the maximum time the call can should take.", + minimum: 1, + optional: true, + }, } }, returns: { @@ -228,6 +241,8 @@ async fn list( snapshot: String, path: String, base64: bool, + json_error: bool, + timeout: Option<u64>, param: Value, ) -> Result<(), Error> { let repo = extract_repository_from_value(¶m)?; @@ -253,10 +268,44 @@ async fn list( None => None, }; - let result = list_files(repo, snapshot, path, crypt_config, keyfile, driver).await?; + let result = if let Some(timeout) = timeout { + match tokio::time::timeout( + std::time::Duration::from_secs(timeout), + list_files(repo, snapshot, path, crypt_config, keyfile, driver), + ) + .await + { + Ok(res) => res, + Err(_) => Err(http_err!(SERVICE_UNAVAILABLE, "list not finished in time")), + } + } else { + list_files(repo, snapshot, path, crypt_config, keyfile, driver).await + }; let output_format = get_output_format(¶m); + if let Err(err) = result { + if !json_error { + return Err(err); + } + let (msg, code) = match err.downcast_ref::<HttpError>() { + Some(HttpError { code, message }) => (message.clone(), Some(code)), + None => (err.to_string(), None), + }; + let mut json_err = json!({ + "error": true, + "message": msg, + }); + if let Some(code) = code { + json_err["code"] = Value::from(code.as_u16()); + } + match output_format.as_ref() { + "json-pretty" => println!("{}", serde_json::to_string_pretty(&json_err)?), + _ => println!("{}", serde_json::to_string(&json_err)?), + } + return Ok(()); + } + let options = default_table_format_options() .sortby("type", false) .sortby("text", false) @@ -266,7 +315,7 @@ async fn list( .column(ColumnConfig::new("size")); format_and_print_result_full( - &mut json!(result), + &mut json!(result.unwrap()), &API_METHOD_LIST.returns, &output_format, &options, -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel