Repository: astral-sh/uv
File: crates/uv-publish/src/lib.rs (Rust)

Code before:
        if status_code == StatusCode::METHOD_NOT_ALLOWED {
            PublishSendError::MethodNotAllowedNoBody
        } else {
            PublishSendError::StatusNoBody(status_code, err)
        }
    })?;
    let upload_error = String::from_utf8_lossy(&upload_error);

    trace!("Response content for non-200 response for {registry}: {upload_error}");

    debug!("Upload error response: {upload_error}");

    // That's most likely the simple index URL, not the upload URL.
    if status_code == StatusCode::METHOD_NOT_ALLOWED {
        return Err(PublishSendError::MethodNotAllowed(
            PublishSendError::extract_error_message(
                upload_error.to_string(),
                content_type.as_deref(),
            ),
        ));
    }

    // Try to parse as RFC 9457 Problem Details (e.g., from pyx).
    if content_type
        .as_deref()
        .is_some_and(|ct| ct == uv_client::ProblemDetails::CONTENT_TYPE)
    {
        if let Some(problem) =
            uv_client::ProblemDetails::try_from_response_body(upload_error.as_bytes())
        {
            if let Some(description) = problem.description() {
                return Err(PublishSendError::StatusProblemDetails(
                    status_code,
                    description,
                ));
            }
        }
    }

    // Raced uploads of the same file are handled by the caller.
    Err(PublishSendError::Status(
        status_code,
        PublishSendError::extract_error_message(upload_error.to_string(), content_type.as_deref()),
    ))
}

#[cfg(test)]
mod tests {
    use std::path::PathBuf;
    use std::sync::Arc;


Review comment (suggestion):
Q: could this use `try_from_response` instead of checking the content-type separately here?

(Alternatively, maybe an `if ... && let ... && let ...` to reduce the rightward drift a bit.)

Code after:
        if status_code == StatusCode::METHOD_NOT_ALLOWED {
            PublishSendError::MethodNotAllowedNoBody
        } else {
            PublishSendError::StatusNoBody(status_code, err)
        }
    })?;
    let upload_error = String::from_utf8_lossy(&upload_error);

    trace!("Response content for non-200 response for {registry}: {upload_error}");

    debug!("Upload error response: {upload_error}");

    // That's most likely the simple index URL, not the upload URL.
    if status_code == StatusCode::METHOD_NOT_ALLOWED {
        return Err(PublishSendError::MethodNotAllowed(
            PublishSendError::extract_error_message(
                upload_error.to_string(),
                content_type.as_deref(),
            ),
        ));
    }

    // Try to parse as RFC 9457 Problem Details (e.g., from pyx).
    if content_type.as_deref() == Some(uv_client::ProblemDetails::CONTENT_TYPE)
        && let Some(problem) =
            uv_client::ProblemDetails::try_from_response_body(upload_error.as_bytes())
        && let Some(description) = problem.description()
    {
        return Err(PublishSendError::StatusProblemDetails(
            status_code,
            description,
        ));
    }

    // Raced uploads of the same file are handled by the caller.
    Err(PublishSendError::Status(
        status_code,
        PublishSendError::extract_error_message(upload_error.to_string(), content_type.as_deref()),
    ))
}

#[cfg(test)]
mod tests {
    use std::path::PathBuf;
    use std::sync::Arc;

    use insta::{allow_duplicates, assert_debug_snapshot, assert_snapshot};
    use itertools::Itertools;
    use uv_auth::Credentials;
    use uv_client::{AuthIntegration, BaseClientBuilder, RedirectPolicy};
    use uv_distribution_filename::DistFilename;