Skip to content
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

Enumerate errors for peek_with_timeout #456

Merged
merged 1 commit into from
Jan 15, 2025
Merged

Conversation

shinghim
Copy link
Contributor

@shinghim shinghim commented Jan 3, 2025

I returned the same values for the new Error case that were previously returned for a None in the peek_default and peek_v1 usages to maintain the same behavior. Maybe it'd be useful to update them to say something about a timeout?

Fixes #396

@coveralls
Copy link
Collaborator

coveralls commented Jan 3, 2025

Pull Request Test Coverage Report for Build 12780541195

Details

  • 19 of 33 (57.58%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.09%) to 60.664%

Changes Missing Coverage Covered Lines Changed/Added Lines %
payjoin-directory/src/lib.rs 12 15 80.0%
payjoin-directory/src/db.rs 7 18 38.89%
Totals Coverage Status
Change from base Build 12771456917: -0.09%
Covered Lines: 2924
Relevant Lines: 4820

💛 - Coveralls

Copy link
Contributor

@DanGould DanGould left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept ACK 7f27c9d, though it seems like a complete this would really entail defining an Error enum containing both RedisResult's RedisError and Elapsed rather than the Ok value being a RedisResult.

Perhaps add one more commit that does that.

A docstring describing the behavior of peek_v1 (or any function) is absolutely appropriate and encouraged.

@shinghim
Copy link
Contributor Author

shinghim commented Jan 4, 2025

Ah makes sense, ill update this hopefully tomorrow

@shinghim shinghim force-pushed the 396-peek branch 2 times, most recently from e92e3a6 to 61bfaf0 Compare January 5, 2025 00:09
@shinghim shinghim marked this pull request as ready for review January 5, 2025 04:34
Copy link
Contributor

@DanGould DanGould left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is what I was looking for.

I think it would be more appropriate for the DbPoolError to be defined in db.rs, (potentially named db::Error) since it's not an error on the whole lib, but rather the db module specifically. Additionally, I would expect a payjoin-directory/src/error.rs to host HandlerError defined as lib.rs too, and since there's only one error type it may not be worth the overhead of new files and imports for the time being.

I also see an opportunity to reduce duplicate code in lib.rs since the pattern is repeated:

fn handle_peek(
    result: Result<Vec<u8>, DbPoolError>,
    timeout_response: Response<BoxBody<Bytes, hyper::Error>>,
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, HandlerError> {
    match result {
        Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
        Err(e) => match e {
            DbPoolError::Redis(re) => Err(HandlerError::BadRequest(re.into())),
            DbPoolError::Timeout(_) => Ok(timeout_response),
        },
    }
}

May you follow up with the module cleanup (putting the new error in db.rs)? The deduplication is optional, since duplicate code is already contained in this repo and keeping it around would not be a regression. But i'd like to see it :)

Thanks for the persistent contributions 🫡

Err(e) => Err(HandlerError::BadRequest(e.into())),
Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
Err(e) => match e {
DbPoolError::Redis(_) => Err(HandlerError::BadRequest(e.into())),
Copy link
Contributor

@DanGould DanGould Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IF we want to return the Redis error to the client (big IF, @nothingmuch what do you think) I think we can return Redis(e) => Err(HandlerError::BadRequest(e.into()) rather than the top level error, since that's the only returned variant. Then Err(_) => match e is appropriate at the higher level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the concern here that Redis will be replaced in the near future (#419), or just generally that the client shouldn't have to worry about the underlying implementation?

Copy link
Contributor

@DanGould DanGould Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exposing internals of the server

  1. isn't generally actionable by most callers
  2. should just be error logged instead and
  3. exposes details about the server state that potentially could be used for an attack. though I'm not sure I can think of one off the top of my head, my idea of best practice is to reveal only that necessary and actionable serverstate for the client to operate and keep everything else private.

Copy link
Collaborator

@nothingmuch nothingmuch Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I concur with Dan (sorry for the late response to this), these errors inform the operator of the directory of the right course of action, and they are the only party that can address this, so IMO this should be printed to error log and result in a 500 error from the directory to the client.

(edit to add: additionally if the appropriate response is bad request, i.e. client's responsibility, that should be detected by the directory before redis ever enters the picture)

@@ -0,0 +1,25 @@
#[derive(Debug)]
pub enum DbPoolError {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be pub(crate) since we don't plan to expose it in the public API.

@shinghim
Copy link
Contributor Author

shinghim commented Jan 5, 2025

Feedback makes sense, I'll move the error and add the dedupe. I'll wait until the Redis error propagation discussion is resolved before pushing all of the updates here at once

@DanGould
Copy link
Contributor

@shinghim Has your question been answered? I think @nothingmuch closed the loop

@shinghim
Copy link
Contributor Author

Sorry was out on vacation but I pushed the changes up

Copy link
Contributor

@DanGould DanGould left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK bfb4a96

Nicely done. Thanks for going above and beyond and generalizing with handle peek. I hope we didn't put too much pressure on you on vacation. You're a joy to collaborate with and I don't think I'm the only one who was eager for your return.

Comment on lines +316 to +319
fn handle_peek(
result: Result<Vec<u8>, Error>,
timeout_response: Response<BoxBody<Bytes, hyper::Error>>,
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, HandlerError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I were forced to come up with one TODO on this PR, or feedback for next time, I would suggest that crate::db::Error were not imported in this file, and rather the function signature was qualified as db::Error since db::Error is not semantically the top level Error for lib.rs. We don't have one, which is why there's no conflict, but HandlerError would be the closest thing.

Writing this also made me notice that some Result types are duplicated in a bunch of places, so there is an argument to be made for

  • db::Result = Result<Vec<u8>, Error>
  • HandlerResult = Result<Response<BoxBody<Bytes, hyper::Error>>, HandlerError>

The result types are really getting nitty gritty but I figure it can't hurt to share

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll open a separate PR to fix these

@DanGould DanGould merged commit 8272492 into payjoin:master Jan 15, 2025
6 checks passed
@shinghim
Copy link
Contributor Author

Nicely done. Thanks for going above and beyond and generalizing with handle peek. I hope we didn't put too much pressure on you on vacation. You're a joy to collaborate with and I don't think I'm the only one who was eager for your return.

Thanks for being so patient, no pressure at all! I hope to keep contributing and have less churn on my PRs as i get more comfortable with the codebase 👍🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enumerate peek_with_timeout errors
4 participants