本文介绍了如何同时使用拒绝和问号运算符处理Warp中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 warp.rs 0.2.2 ,让我们考虑一个基本Web服务,其中一条路由用于 GET/:

Using warp.rs 0.2.2, let's consider a basic web service with one route for GET /:

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
    let getRoot = warp::get().and(warp::path::end()).and_then(routes::getRoot);
    warp::serve(getRoot).run(([0, 0, 0, 0], 3030)).await;
    Ok(())
}

我的目标是在路由处理程序中使用?进行错误处理,因此让我们写一个可以出错并在 crate :: routes :

My goal is to use ? for error handling in the route handlers, so let's write one that can error and return early in crate::routes:

use crate::errors::ServiceError;
use url::Url;

pub async fn getRoot() -> Result<impl warp::Reply, warp::Rejection> {
    let _parsed_url = Url::parse(&"https://whydoesn.it/work?").map_err(ServiceError::from)?;

    Ok("Hello world !")
}

此版本有效.在这里, Url :: parse()返回的错误是 url :: ParseError

This version works.Here the error that's returned by Url::parse() is a url::ParseError

要在错误类型之间进行转换,请从 url :: ParseError 转换为 ServiceError ,然后从 ServiceError 转换为 warp :: Rejection ,我在 crate :: errors :

To convert between error types, from url::ParseError to ServiceError, then from ServiceError to warp::Rejection, I've written some error helpers in crate::errors:

#[derive(thiserror::Error, Debug)]
pub enum ServiceError {
    #[error(transparent)]
    Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
}
impl warp::reject::Reject for ServiceError {}
impl From<ServiceError> for warp::reject::Rejection {
    fn from(e: ServiceError) -> Self {
        warp::reject::custom(e)
    }
}
impl From<url::ParseError> for ServiceError {
    fn from(e: url::ParseError) -> Self {
        ServiceError::Other(e.into())
    }
}


现在,上面的方法起作用了,我正在尝试缩短第二个代码块以直接使用?进行错误处理,并自动从基础错误中进行转换(此处为 url ::ParseError )转换为 warp :: Rejection .这是我尝试过的:


Now, the above works, and I'm trying to shorten the second code block to use ? for error handling directly, and convert automatically from the underlying error (here url::ParseError) to a warp::Rejection.Here's what I've tried:

use crate::errors::ServiceError;
use url::Url;

pub async fn getRoot() -> Result<impl warp::Reply, ServiceError> {
    let _parsed_url = Url::parse(&"https://whydoesn.it/work?")?;

    Ok("Hello world !")
}

Url :: Parse 返回的 url :: ParseError 可以很好地转换为ServiceError以返回,但是从我的处理程序中返回ServiceError不起作用.我得到的第一个编译错误是:

The url::ParseError returned by Url::Parse will convert fine into a ServiceError to return, but returning a ServiceError from my handler doesn't work.The first compilation error I get is:

error[E0277]: the trait bound `errors::ServiceError: warp::reject::sealed::CombineRejection<warp::reject::Rejection>` is not satisfied
   --> src/main.rs:102:54
    |
102 |     let getRoot = warp::get().and(warp::path::end()).and_then(routes::getRoot);
    |                                                      ^^^^^^^^ the trait `warp::reject::sealed::CombineRejection<warp::reject::Rejection>` is not implemented for `errors::ServiceError`

有没有办法让我仅使用来保持简短的错误处理?和以下任何一种方式:

Is there a way I can keep the short error handling using ? only and either:

  • 使 ServiceError 实现 warp :: reject :: sealed :: CombineRejection< warp :: reject :: Rejection> 吗?
  • 解决这个问题吗?

推荐答案

从我的发现中,有两种解决方案.

From my findings, there are two solutions.

  1. 放弃?,转而支持您自己的宏,该宏可以构造并在出现错误时返回响应.

  1. Abandon ? in favor of your own macro that constructs and returns a response if there is an error.

使用cjbassi的 PR#458 代替由:

Use PR #458 by cjbassi instead of the mainline release by:

  • 对错误类型实施 warp :: reply :: Reply ,以便将其转换为正确的面向用户的错误消息.
  • warp ="0.2" 替换为 warp = {git ="https://github.com/cjbassi/warp.git",分支="error";} 在您的Cargo.toml文件中
  • 使用 .map_async 代替 .and_then 作为处理程序
  • Implementing warp::reply::Reply on your error type so that it converts into the correct user facing error message.
  • Replace warp = "0.2" with warp = { git = "https://github.com/cjbassi/warp.git", branch = "error"} in your Cargo.toml file
  • use .map_async instead of .and_then for handlers

这篇关于如何同时使用拒绝和问号运算符处理Warp中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 19:58