-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce header provider trait #31
base: main
Are you sure you want to change the base?
Conversation
pub trait VssHeaderProvider { | ||
/// Returns the HTTP headers to be used for a VSS request. | ||
/// This method is called on each request, and should likely perform some form of caching. | ||
async fn get_headers(&self, request: &[u8]) -> Result<HashMap<String, String>, VssError>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++
request
: A reference to serialized request body. It can be used to perform operations such as request signing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
#[async_trait] | ||
impl VssHeaderProvider for FixedHeaders { | ||
async fn get_headers(&self, _request: &[u8]) -> Result<HashMap<String, String>, VssError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returning some of the errors in VssError can have unintended consequences such as NoSuchKey/Conflict, or in some cases misleading.
the alternative is, we use io::Result<HashMap<String,String>> here and blanket convert all errors to VssError::AuthError in VssClient. (i think this would be much easier to debug and easy to understand from api perspective)
or we could document that only
InvalidRequestError, (invalid request by user or invalid input)
AuthError, (in case of auth failure) (or blanket convert all errors to authError)
InternalServerError, (auth server unavailable)
InternalError (unexpected code failure) (if the failure could be because of user provided input, it should still be invalid request, for example an error due to user provided headers or seed)
should be used here and explain how they will be used for auth_provider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree, this was the main reason I initially created a separate error type. Moved to io::Result
which will be embedded in VssError::AuthError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good,
I was also good with the way we have done error handling in lnurlauthprovider, it would just need some explaining in trait docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid if we want to expose/use this interface in LDK Node bindings, we need to revert the recent changes as discussed in #26. We need to keep the simpler error types as io::Error
is probably not feasible to expose in bindings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, I forgot whether this will turn out internal in ldk-node
or exposed as bindings. We did discuss the option of having this exposed as bindings, so I changed this into Result<_, String>
to not have different semantics around VssError
for different cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me !
As we don't have any way of handling more granular error types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, I forgot whether this will turn out internal in
ldk-node
or exposed as bindings. We did discuss the option of having this exposed as bindings, so I changed this intoResult<_, String>
to not have different semantics aroundVssError
for different cases.
Unfortunately the error type must be an enum
and implement std::error::Error
(see https://mozilla.github.io/uniffi-rs/udl/errors.html), so I think we really have to revert to what we had discussed before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, in that case lets just revert to using VssError, we are using it correctly in lnurl PR.
and have some docs in this trait as discussed in first comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks for mentioning that! I should have double-checked UniFFI. Reverted back to VssError
and added documentation in the trait. Enforced all VssHeaderProvider errors to be a single variant i.e. VssError::AuthError
to not conflate semantics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, in that case lets just revert to using VssError, we are using it correctly in lnurl PR. and have some docs in this trait as discussed in first comment.
No, I really meant it, we should revert to the simple error type: UniFFI doesn't support tuple structs/enums. If we want to use VssError
, it can't have any such variants, i.e., VssError::AuthError(String)
would need to become AuthError(error: String)
etc. It also shouldn't rely on any constructors/methods, as otherwise needs to be exposed differently.
Reverting back to what we previously discussed seems much simpler.
src/client.rs
Outdated
.get_headers(&request_body) | ||
.await | ||
.map_err(|e| VssError::InternalError(e.to_string()))?; | ||
let headermap = get_headermap(&headers).map_err(VssError::InternalError)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we can't get string value header map from headers, then there is probably some user provided invalid input.
i think this can be InvalidRequestError.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the discussion above, using io::Error
that will be embedded in VssError::AuthError
. These might also be invalid headers by the provider.
c2d1d00
to
9e151a4
Compare
FYI I am aiming to get this merged first before rebasing #26 if that sounds good. |
/// Any returned errors should be of the `VssError::AuthError` variant, | ||
/// or will be mapped to it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Any returned errors should be of the `VssError::AuthError` variant, | |
/// or will be mapped to it. | |
/// Any returned errors must be of the `VssError::AuthError` variant. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, lets link to it, i.e.
/// Any returned errors should be of the `VssError::AuthError` variant, | |
/// or will be mapped to it. | |
/// Any returned errors should be of the [`VssError::AuthError`] variant, | |
/// or will be mapped to it. |
.map_err(|e| match e { | ||
e @ VssError::AuthError(_) => e, | ||
e => VssError::AuthError(e.to_string()), | ||
})?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map_err(|e| match e { | |
e @ VssError::AuthError(_) => e, | |
e => VssError::AuthError(e.to_string()), | |
})?; | |
.map_err(|e| match e { | |
VssError::AuthError(_) => e, | |
_ => VssError::AuthError(e.to_string()), | |
})?; |
nit: @ Binding seems unnecessary here.
.get_headers(&request_body) | ||
.await | ||
.and_then(get_headermap) | ||
.map_err(|e| match e { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add a simple testcase for this ?
@@ -34,7 +39,19 @@ impl<R: RetryPolicy<E = VssError>> VssClient<R> { | |||
|
|||
/// Constructs a [`VssClient`] from a given [`reqwest::Client`], using `base_url` as the VSS server endpoint. | |||
pub fn from_client(base_url: &str, client: Client, retry_policy: R) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If we end up owning the value anyways, we could consider just taking a String
here and below.
/// Any returned errors should be of the `VssError::AuthError` variant, | ||
/// or will be mapped to it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, lets link to it, i.e.
/// Any returned errors should be of the `VssError::AuthError` variant, | |
/// or will be mapped to it. | |
/// Any returned errors should be of the [`VssError::AuthError`] variant, | |
/// or will be mapped to it. |
|
||
#[async_trait] | ||
impl VssHeaderProvider for FixedHeaders { | ||
async fn get_headers(&self, _request: &[u8]) -> Result<HashMap<String, String>, VssError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, in that case lets just revert to using VssError, we are using it correctly in lnurl PR. and have some docs in this trait as discussed in first comment.
No, I really meant it, we should revert to the simple error type: UniFFI doesn't support tuple structs/enums. If we want to use VssError
, it can't have any such variants, i.e., VssError::AuthError(String)
would need to become AuthError(error: String)
etc. It also shouldn't rely on any constructors/methods, as otherwise needs to be exposed differently.
Reverting back to what we previously discussed seems much simpler.
Introduces a HeaderProvider trait that will provide headers for each VSS call.
This change is split off from #26, which will introduce a JWT header provider based on LNURL Auth.