Requests icon indicating copy to clipboard operation
Requests copied to clipboard

Requests: Add "requests.failed" hook

Open pprkut opened this issue 4 years ago • 15 comments

Pull Request Type

  • [x] I have checked there is no other PR open for the same change.

This is a:

  • [ ] Bug fix
  • [x] New feature
  • [ ] Code quality improvement

Context

This allows to inspect or alter the exception that is thrown to the user in case of transport errors, or in case of response parsing problems.

Detailed Description

We use the hooks to gather analytics about the remote requests we make in out platform, but failed requests slipped through the cracks since there is currently no way to track those. You can get some analytics from when you make the request, but you won't know from just that whether it failed. We'd also like to know why it failed, the error message that was returned, etc.

We've been using the hook in our platform for a couple weeks now and it worked fine for us :) (Although we've applied this change to 1.8.x)

Quality assurance

  • [x] This change does NOT contain a breaking change (fix or feature that would cause existing functionality to change).
  • [x] I have commented my code, particularly in hard-to-understand areas.
  • [x] I have added unit tests to accompany this PR.
  • [x] The (new/existing) tests cover this PR 100%.
  • [x] I have (manually) tested this code to the best of my abilities.
  • [x] My code follows the style guidelines of this project.

Documentation

For new features:

  • [ ] I have added a code example showing how to use this feature to the examples directory.
  • [x] I have added documentation about this feature to the docs directory. If the documentation is in a new markdown file, I have added a link to this new file to the Docs folder README.md file.

pprkut avatar Oct 26 '21 14:10 pprkut

Thank you @pprkut . I'm not adverse to this change, but would like to see it covered by unit tests.

jrfnl avatar Oct 26 '21 15:10 jrfnl

Sure thing, just a bit confused by the test organization 😅 If someone could give me a pointer of where the test(s) should be added, I would much appreciate it.

pprkut avatar Oct 26 '21 15:10 pprkut

Sure thing, just a bit confused by the test organization 😅 If someone could give me a pointer of where the test(s) should be added, I would much appreciate it.

I think the most appropriate place for the tests would be in the RequestsTest class as the hook is being added to the Requests class.

If needs be, we can always move it later (we're working on improving the test suite).

If you need some inspiration on how to test the hook, you may want to have a look at the following tests: https://github.com/WordPress/Requests/blob/28879ed125baee3e9caf09d9ff3a749fb86777ba/tests/Transport/BaseTestCase.php#L924-L957

jrfnl avatar Nov 01 '21 02:11 jrfnl

Thank you @jrfnl! I will take a look!

pprkut avatar Nov 03 '21 19:11 pprkut

@pprkut Just checking in to see how it's going...

jrfnl avatar Nov 26 '21 00:11 jrfnl

@jrfnl I still have it on my list, but haven't found the time yet :-/ It's still gonna take me some time. My goal would be to finish this up before the end of the year

pprkut avatar Nov 26 '21 06:11 pprkut

@jrfnl I think I got all the different test cases. Let me know what you think :)

I'm also fine squashing the commits, etc. Just focused on getting the tests in for now

pprkut avatar Dec 17 '21 19:12 pprkut

@pprkut,

Thanks for the work on this PR so far!

I have been thinking about this some more, and I actually fail to see what the use case is where you would need this action. I'm not opposed to adding actions, but they need to add something to warrant their added maintenance cost. Here, I'm not sure this is the case. Maybe you can help me figure this out.

The way I see it right now, you could get everything you need by adding a try/catch block around the Requests::request() call, instead of doing the call right away and then listening on a requests/failed hook for a possible exception.

Do you have a use case in mind where just adding a try/catch block around Requests::request() would not be enough or not be feasible?

schlessera avatar Apr 25 '22 08:04 schlessera

@schlessera Sure, I'll try to outline our usecase :)

We use the hooks to collect analytics about all HTTP requests that our system makes. The end result then looks like this:

Screenshot_20220425_110644

The hooks we use are:

  • requests.before_request
  • curl.after_request
  • requests.before_redirect
  • requests.after_request

The way it works is that requests.before_request initiates the analytics data, but we need the response data to finalize it. curl.after_request adds IP information to the analytics, requests.before_redirect finalizes a request with a 301 response (for example), and requests.after_request finalizes all other successful requests.

However, if a request fails, because of wrong options or curl errors, we have the analytics data initiated, but no other hook is triggered so we never get an indicator that the request is "completed" (and that means the anayltics are never stored and won't show on that dashboard). We could do that with exception handling on our side of the code, but then we'd have to either do that everywhere we make an HTTP request with Requests and call the analytics library in all those places to indicate the request is completed and failed, or implement a wrapper around Requests that does that exception handling. But that just seems weird and clunky since most of the functionality is already handled via hooks.

Adding the requests.failed hook looked like the cleanest way to implement this, and would also allow other people to do something similar. That's why I went in that direction.

pprkut avatar Apr 25 '22 09:04 pprkut

Rebased, and I think the "Status: needs tests" label can go now since it has tests.

SMillerDev avatar Aug 08 '22 11:08 SMillerDev

Rebased after doing some work on our fork accidentally dropped some commits.

SMillerDev avatar Oct 26 '22 14:10 SMillerDev

@pprkut PR #833 has just been merged, which should allow for simplifying the tests in this PR. Would you like to update the PR ? Or do you expect us to get your PR to a mergable state ?

jrfnl avatar Feb 12 '24 11:02 jrfnl

@jrfnl I've been following along the other PR :slightly_smiling_face: I'm on vacation right now until the weekend, but I'll see what I can do to get this PR updated :+1:

pprkut avatar Feb 12 '24 15:02 pprkut

@pprkut Excellent! Take your time and I look forward to seeing the next iteration. In the mean time: enjoy your break!

jrfnl avatar Feb 12 '24 16:02 jrfnl

@jrfnl Should be updated :slightly_smiling_face:

pprkut avatar Feb 28 '24 10:02 pprkut