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

topdown/http: handle http.send errors in-band #2763

Merged

Conversation

ashutosh-narkar
Copy link
Member

This change updates how errors from http.send are handled.
By default, an error returned by http.send halts the policy evaluation.
This commit allows users to return errors in the response object
returned by http.send instead of halting evaluation.

Fixes: #2187

Signed-off-by: Ashutosh Narkar anarkar4387@gmail.com

Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

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

I think the implementation could be a improved a bit.

I'm wondering about the format of the error in the result...as a user, looking at the docs and even the test cases, it was unclear how I'm supposed to consume the error--it's just a string and the content could be pretty much anything. I wonder if we should make the error a bit more structured and indicate the different kinds of failures, e.g., a bad parameter is essentially an internal error whereas a network error could be distinguished. Something like:

"error": {
   "code": "eval_http_send_internal_error",
   "message": "..."
}
"error": {
   "code": "eval_http_send_network_error",
   "message": "..."
}

@patrick-east thoughts?

@@ -879,10 +880,16 @@ The `response` object parameter will contain the following fields:
| Field | Type | Description |
| --- | --- | --- |
| `status` | `string` | HTTP status message (e.g., `"200 OK"`). |
| `status_code` | `number` | HTTP status code (e.g., `200`). |
| `status_code` | `number` | HTTP status code (e.g., `200`). If `raise_error` is `false`, this field will be set to `0`. |
Copy link
Member

Choose a reason for hiding this comment

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

Nit: the description is a bit ambiguous; presumably the status_code is only zero if there was some unexpected error, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. Updated the description.

topdown/http.go Outdated
return builtinHTTPSendHelper(bctx, req, raiseError, iter)
}

func builtinHTTPSendHelper(bctx BuiltinContext, req ast.Object, raiseError bool, iter func(*ast.Term) error) (err error) {
Copy link
Member

Choose a reason for hiding this comment

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

I think this code can be simplified quite a bit: https://gist.github.com/tsandall/deeaff535f9eaae5a55559067611473e

There are a couple red flags:

  • the httpSendErrType variable is a bit brittle. E.g., if we add another error path in the future, we need to make sure to set the variable accordingly; if we forget, the built-in won't behave correctly.

  • the defer block is re-executing the iterator; this means the search after this expression will be re-evaluated unnecessarily

  • generally, appending "helper" to a function name is an indicator that the function is doing too much--in this case, the solution is to split the iterator invocation from the http request execution--that avoids the need for the defer and the boolean.

Copy link
Member Author

Choose a reason for hiding this comment

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

Refactored the code as per your comment.

@ashutosh-narkar
Copy link
Member Author

I think the implementation could be a improved a bit.

I'm wondering about the format of the error in the result...as a user, looking at the docs and even the test cases, it was unclear how I'm supposed to consume the error--it's just a string and the content could be pretty much anything. I wonder if we should make the error a bit more structured and indicate the different kinds of failures, e.g., a bad parameter is essentially an internal error whereas a network error could be distinguished. Something like:

"error": {
   "code": "eval_http_send_internal_error",
   "message": "..."
}
"error": {
   "code": "eval_http_send_network_error",
   "message": "..."
}

Updated the error in the response to be an object containing the error code and message.

tsandall
tsandall previously approved these changes Oct 9, 2020
Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

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

LGTM

This change updates how errors from http.send are handled.
By default, an error returned by `http.send` halts the policy evaluation.
This commit allows users to return errors in the response object
returned by `http.send` instead of halting evaluation.

Fixes: open-policy-agent#2187

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
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.

Handle http.send errors in-band
2 participants