While trying to get started with development of an api using rocket, I was implementing a request guard which is supposed to check authorization headers. When the check fails it should result in a Failure, but that is where I cannot get it to work. Outcome::Success
works perfectly fine and returns the correct object, but when triggering an Outcome::Failure
I always run into the issue that I cannot get it to compile:
[package]
name = "api-sandbox"
version = "0.1.0"
edition = "2021"
[dependencies]
rocket = "0.5.0-rc.1"
regex = "1"
#[macro_use] extern crate rocket;
use rocket::Request;
use rocket::request::{FromRequest, Outcome};
use rocket::http::Status;
use regex::Regex;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[get("/test")]
fn test(device: Device) -> &'static str {
"Hello test"
}
#[derive(Debug)]
enum RequestError {
InvalidCredentials,
ParseError,
}
struct Device {
id: i32
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Device {
type Error = RequestError;
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
Outcome::Failure((Status::BadRequest, RequestError::ParseError));
// TEST
let d1 = Device {
id: 123
};
Outcome::Success(d1)
}
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index,test])
}
error[E0282]: type annotations needed
--> src/main.rs:43:21
|
43 | Outcome::Failure((Status::BadRequest, RequestError::ParseError));
| ^^^^^^^^^^^^^^^^ cannot infer type for type parameter S declared on the enum Outcome
I expected that the parameter S
should not needed to be declared, as I am not using the parameter Success(S)
, but use Failure(E)
. According to the docs I can either return an error or an tuple with Status
and Error
, but instead the error message pops up. I have double checked with only available resources and blogs, but was not able to correctly trigger an outcome with status failure.
The type of Outcome::Failure(_)
cannot be deduced. Even if not used in this particular construction, the type parameter S
must be known for it to be a complete type. There is no default type available or any context that can help infer the type of S
.
The same is true of Outcome::Success(_)
. By itself, the type of the template parameter E
is not known. However, this compiles because it does have context that can help the compiler infer it. It is used as a return value, so it must match the return type, and therefore it can be deduced that E
is Self::Error
.
This will also work for Outcome::Failure(_)
if it were used as a return value:
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
Outcome::Failure((Status::BadRequest, RequestError::ParseError))
}