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

feat: access-api proxy.js has configurable options.catchInvocationError, by default catches HTTPError -> error result w/ status=502 #366

Merged
merged 3 commits into from
Jan 19, 2023

Conversation

gobengo
Copy link
Contributor

@gobengo gobengo commented Jan 19, 2023

, which defaults to something that catches HTTPErrors and rewrites to a status=502 error result

Motivation:

Limitations

  • This inlcudes in result['x-proxy-error'] any info from the underlying @ucanto/transport/http HTTPError, but unless/until we put more info on that error, we still won't have the raw response object and e.g. won't have response headers.
    • but if those properties are ever added to HTTPError, they should show up in x-proxy-error

…ich defaults to something that catches HTTPErrors and rewrites to a status=502 error result
@gobengo gobengo changed the title access-api proxy.js has configurable options.catchInvocationError access-api proxy.js has configurable options.catchInvocationError, by default catches HTTPError -> error result w/ status=502 Jan 19, 2023
@gobengo gobengo requested a review from Gozala January 19, 2023 01:09
@gobengo gobengo changed the title access-api proxy.js has configurable options.catchInvocationError, by default catches HTTPError -> error result w/ status=502 feat: access-api proxy.js has configurable options.catchInvocationError, by default catches HTTPError -> error result w/ status=502 Jan 19, 2023
@gobengo gobengo temporarily deployed to dev January 19, 2023 01:10 — with GitHub Actions Inactive
Comment on lines +78 to +81
issuer: proxyInvocationIssuer,
capability: capabilities[0],
audience,
proofs: [invocationIn],
Copy link
Contributor

@hugomrdias hugomrdias Jan 19, 2023

Choose a reason for hiding this comment

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

we should add the other props from invocationIn like expiration, etc

Copy link
Contributor

Choose a reason for hiding this comment

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

github is forcing me to add another comments because i approved instead of requesting changes lol

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Why? I don't think that will add anything. All that info will already be in the resulting proxyInvocation proof chain because the whole invocationIn (including its expiration is in proofs). wdyt @Gozala
  2. That's not related to the point of this PR, so if you're proposing changing the proxy logic, let's do it as a separate issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why? I don't think that will add anything. All that info will already be in the resulting proxyInvocation proof chain because the whole invocationIn (including its expiration is in proofs). wdyt @Gozala

You are correct that expiration in the invocationIn will restrict time bounds, however if you do not specify expiration here it will automatically default to 30secs (if I'm not mistaken), which is to say it may be shorter than what's in the invocationIn.

In other words I think it is a good idea to include expiration and notBefore.

Copy link
Contributor

Choose a reason for hiding this comment

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

This also prompted me to look at take another look at the spec and it seems to state

All proofs MUST contain time bounds equal to or broader than the UCAN being delegated. If the proof expires before the outer UCAN — or starts after it — the reader MUST treat the UCAN as invalid.

Which is to say that UCANs that not copying those time bounds would render a UCAN invalid, that said I'm not sure if this is how ucanto does it, but I'll check

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah I didn't realize it would default.

44a054b

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which is to say that UCANs that not copying those time bounds would render a UCAN invalid, that said I'm not sure if this is how ucanto does it, but I'll check

I read it differently... in this case of proxying, the incoming invocationIn becomes the proof. Let's say it expires in 24hrs. Let's say without copying over that expiry, the proxyInvocation gets created with a 30sec expiry.

All proofs MUST contain time bounds equal to or broader than the UCAN being delegated.

The time bounds of the proof invocationIn is [t0, 0 + 24hrs]. The time bounds of 'the UCAN being delegated' I think is the proxyInvocation whose time bounds is [t1, t1 + 30sec]. Assuming t1 - t0 ~= 0, then I think it's fair to say the time bounds of the proof are broader than the invocation/delegation.

If the proof expires before the outer UCAN — or starts after it — the reader MUST treat the UCAN as invalid.

The proof would not expire before the 'outer UCAN'.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it would be bad if invocationIn expiry was like 15sec, and the proxyInvocation expiry defaulted to 30sec. So that makes it worth copying the expiration for that scenario

Comment on lines +78 to +81
issuer: proxyInvocationIssuer,
capability: capabilities[0],
audience,
proofs: [invocationIn],
Copy link
Contributor

Choose a reason for hiding this comment

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

github is forcing me to add another comments because i approved instead of requesting changes lol

@gobengo gobengo temporarily deployed to dev January 19, 2023 18:21 — with GitHub Actions Inactive
Copy link
Contributor

@hugomrdias hugomrdias left a comment

Choose a reason for hiding this comment

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

To make sure i understand this catches upload api 500s and instead of throwing returns a generic Bad Gateway with the error in x-proxy-error ?

*/
function defaultCatchInvocationError(error) {
const badGatewayResult = BadGatewayHTTPErrorResult.catch(error)
if (badGatewayResult) {
Copy link
Contributor

Choose a reason for hiding this comment

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

we should probably send error to sentry here

return result
} catch (error) {
if (catchInvocationError) {
const caughtResult = await catchInvocationError(error)
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need this to be a promise ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, but resolving a returned promise is intentional so the process of building a result from the error can be async.

Copy link
Contributor

@Gozala Gozala left a comment

Choose a reason for hiding this comment

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

Since @hugomrdias is reviewing this I'll let him handle this.

@gobengo
Copy link
Contributor Author

gobengo commented Jan 19, 2023

To make sure i understand this catches upload api 500s and instead of throwing returns a generic Bad Gateway with the error in x-proxy-error ?

@hugomrdias yes

Copy link
Contributor

@hugomrdias hugomrdias left a comment

Choose a reason for hiding this comment

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

LGTM, only thing missing is sending to sentry the error but that is not blocking

@gobengo gobengo merged commit c8ca473 into main Jan 19, 2023
@gobengo gobengo deleted the 1674089929-proxy-bad-gateway branch January 19, 2023 19:08
gobengo pushed a commit that referenced this pull request Jan 19, 2023
🤖 I have created a release *beep* *boop*
---


##
[4.6.0](access-api-v4.5.0...access-api-v4.6.0)
(2023-01-19)


### Features

* access-api proxy.js has configurable options.catchInvocationError, by
default catches HTTPError -> error result w/ status=502
([#366](#366))
([c8ca473](c8ca473))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
gobengo added a commit that referenced this pull request Apr 11, 2023
…or, by default catches HTTPError -> error result w/ status=502 (#366)

, which defaults to something that catches HTTPErrors and rewrites to a
status=502 error result

Motivation:
* relates to: #363
* instead of that behavior of getting a `HandlerExecutionError` (due to
internally having an uncaught `HTTPError`), after this PR we should
* not have the uncaught `HTTPError`, so no uncaught
`HandlerExecutionError`
* the result will have `status=502` and `x-proxy-error` with information
about the proxy invocation request that errored (which will help debug
#363)

Limitations
* This inlcudes in `result['x-proxy-error']` any info from the
underlying `@ucanto/transport/http` `HTTPError`, but unless/until we put
more info on that error, we still won't have the raw response object and
e.g. won't have response headers.
* but if those properties are ever added to `HTTPError`, they should
show up in `x-proxy-error`
gobengo pushed a commit that referenced this pull request Apr 11, 2023
🤖 I have created a release *beep* *boop*
---


##
[4.6.0](access-api-v4.5.0...access-api-v4.6.0)
(2023-01-19)


### Features

* access-api proxy.js has configurable options.catchInvocationError, by
default catches HTTPError -> error result w/ status=502
([#366](#366))
([57d0fa4](57d0fa4))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants