WIP: Add user defined OnBeforeRequest middlewares on all response paths, improve documentation
Work for #356
Codecov Report
Merging #372 into master will decrease coverage by
0.28%. The diff coverage is69.23%.
@@ Coverage Diff @@
## master #372 +/- ##
==========================================
- Coverage 96.19% 95.90% -0.29%
==========================================
Files 10 10
Lines 1235 1246 +11
==========================================
+ Hits 1188 1195 +7
- Misses 26 29 +3
- Partials 21 22 +1
| Impacted Files | Coverage Δ | |
|---|---|---|
| client.go | 95.56% <69.23%> (-1.16%) |
:arrow_down: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update d2ba00f...b5d18e3. Read the comment docs.
I made the suggested changes
Any reason, why these two (responseLogger, parseResponseBody) response middleware is not called in the proposal? At least I think logger one needs to be executed.
I would like to be able to use a custom logger (at least in my use case), and I can see the default responseLogger mw injected which is debug only as a basis for #345. parseResponseBody, at least, can be disabled via SetDoNotParseResponse, but I can't see a similar experience for this one yet (please correct me if I'm wrong)
For the general case of intercepting all return paths (including errors where responses can be in an invalid state) I'd leave that responsibility up to the user and their middleware implementation (unless otherwise specified in the documentation like the body drain mentions)
To clarify a bit more about the use case: my application is designed to support debug flows on a per-request basis based on a flag so the current per-client configuration doesn't really fit and a user defined middleware in this setup could allow for per-request behaviors without coupling to the internal middlewares
@lggomez I see your viewpoint and use case. Let's do the following -
- With this PR, let's stick to current behavior, .i.e execute
responseLogger,parseResponseBodymiddleware for all paths along with user-defined ones. - As part #345 solution exposing all middlewares to resty users via new sub-package 🤔 . This is maybe a breaking change, need to analyze a bit.
- Also bringing debug setting per request is also an option.
Sounds like a plan?
All of them sound fine; for the scope of the PR I'd keep with implementing just the first item for now
Regarding that, one of the issues of moving the internal middleware to all paths is that suddenly the applyResponseMiddlewares has to return an error:
- For error paths, we don't use the error returned by it (it will break behavior and tests otherwise)
- For the normal return path, use its error result for the
wrapNoRetryErr(err)return value
I pushed the current change, so I'll await your opinion on this
For error paths, we don't use the error returned by it (it will break behavior and tests otherwise)
@lggomez Do you mean returning an error of response middleware from L852, L866, and L875 it will break the existing behavior?
If it is not returned; then the previous error is getting eaten/suppressed by resty, isn't it?. Typically any libraries shouldn't eat any errors, only the end-user can make a decision on ignoring the error.
Yeah, changing
c.applyResponseMiddlewares(response)
return response, err
to
return response, c.applyResponseMiddlewares(response)
breaks the following (only on the first early return on the execute() method):
--- FAIL: TestClientRedirectPolicy (0.03s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x18 pc=0x77746d]
goroutine 84 [running]:
testing.tRunner.func1.1(0x815340, 0xbe0890)
C:/Go/src/testing/testing.go:988 +0x314
testing.tRunner.func1(0xc0001e8a20)
C:/Go/src/testing/testing.go:991 +0x400
panic(0x815340, 0xbe0890)
C:/Go/src/runtime/panic.go:969 +0x174
github.com/go-resty/resty/v2.TestClientRedirectPolicy(0xc0001e8a20)
C:/Users/a309586/DEV/GITHUB/resty/client_test.go:110 +0x2dd
testing.tRunner(0xc0001e8a20, 0x8a7428)
C:/Go/src/testing/testing.go:1039 +0xe3
created by testing.(*T).Run
C:/Go/src/testing/testing.go:1090 +0x379
This issue aside, the applyResponseMiddlewares() error would be shadowing the original execute() error, so doing this right is a bit hairier than I thought initially. We want to be able to cancel the middleware stack but we also want to be able to propagate accordingly the errors (maybe wrap the mw error?)
@lggomez I'm sorry for the delay in response.
I think wrapping the error will be a good choice. Please go ahead. Thanks.
Also, streamlining this part in the next major version as breaking change will help everyone.