Repository: juspay/hyperswitch
File: crates/router/src/core/errors/utils.rs (Rust)

Code before:
    fn to_duplicate_response(
        self,
        duplicate_response: errors::CustomersErrorResponse,
    ) -> error_stack::Result<T, errors::CustomersErrorResponse> {
        self.map_err(|err| {
            if err.current_context().is_db_unique_violation() {
                err.change_context(duplicate_response)
            } else {
                err.change_context(errors::CustomersErrorResponse::InternalServerError)
            }
        })
    }
}

impl<T> StorageErrorExt<T, errors::ApiErrorResponse>
    for error_stack::Result<T, errors::StorageError>
{
    #[track_caller]
    fn to_not_found_response(
        self,
        not_found_response: errors::ApiErrorResponse,
    ) -> error_stack::Result<T, errors::ApiErrorResponse> {
        self.map_err(|err| {
            let new_err = match err.current_context() {
                errors::StorageError::ValueNotFound(_) => not_found_response,
                errors::StorageError::DecryptionError => not_found_response,
                errors::StorageError::CustomerRedacted => {
                    errors::ApiErrorResponse::CustomerRedacted
                }
                _ => errors::ApiErrorResponse::InternalServerError,
            };
            err.change_context(new_err)
        })
    }

    #[track_caller]
    fn to_duplicate_response(
        self,
        duplicate_response: errors::ApiErrorResponse,
    ) -> error_stack::Result<T, errors::ApiErrorResponse> {
        self.map_err(|err| {
            let new_err = match err.current_context() {
                errors::StorageError::DuplicateValue { .. } => duplicate_response,
                _ => errors::ApiErrorResponse::InternalServerError,
            };
            err.change_context(new_err)
        })
    }
}

pub trait ConnectorErrorExt<T> {

Review comment (bug):
Why is `DecryptionError` error mapped to `not_found_response` ?
DecryptionError can occur incase of wrong DEK (data encryption key as well right) ?

Code after:
    fn to_duplicate_response(
        self,
        duplicate_response: errors::CustomersErrorResponse,
    ) -> error_stack::Result<T, errors::CustomersErrorResponse> {
        self.map_err(|err| {
            if err.current_context().is_db_unique_violation() {
                err.change_context(duplicate_response)
            } else {
                err.change_context(errors::CustomersErrorResponse::InternalServerError)
            }
        })
    }
}

impl<T> StorageErrorExt<T, errors::ApiErrorResponse>
    for error_stack::Result<T, errors::StorageError>
{
    #[track_caller]
    fn to_not_found_response(
        self,
        not_found_response: errors::ApiErrorResponse,
    ) -> error_stack::Result<T, errors::ApiErrorResponse> {
        self.map_err(|err| {
            let new_err = match err.current_context() {
                errors::StorageError::ValueNotFound(_) => not_found_response,
                errors::StorageError::CustomerRedacted => {
                    errors::ApiErrorResponse::CustomerRedacted
                }
                _ => errors::ApiErrorResponse::InternalServerError,
            };
            err.change_context(new_err)
        })
    }

    #[track_caller]
    fn to_duplicate_response(
        self,
        duplicate_response: errors::ApiErrorResponse,
    ) -> error_stack::Result<T, errors::ApiErrorResponse> {
        self.map_err(|err| {
            let new_err = match err.current_context() {
                errors::StorageError::DuplicateValue { .. } => duplicate_response,
                _ => errors::ApiErrorResponse::InternalServerError,
            };
            err.change_context(new_err)
        })
    }
}

pub trait ConnectorErrorExt<T> {
    #[track_caller]