Fix delete requests crashing before they reach the API - #30
Open
eastagiletracker wants to merge 1 commit into
Open
Fix delete requests crashing before they reach the API#30eastagiletracker wants to merge 1 commit into
eastagiletracker wants to merge 1 commit into
Conversation
Connection#process_request returned the params object unchanged when it was empty, so the default empty Hash reached Faraday as the request body and Net::HTTP raised NoMethodError on Hash#bytesize before any bytes were written. webhooks.delete, custom_fields.delete and broadcasts.delete could never complete, and neither could tags.update or subscribers.update when called with no changed fields. custom_fields.delete and broadcasts.delete additionally read success? off the parsed response body rather than the response itself, so they now ask for the raw response the way tags.remove_from_subscriber already does.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR proposes a fix for
webhooks.delete,custom_fields.deleteandbroadcasts.delete, which raiseNoMethodErrorinside Faraday before the request ever reaches the API. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/493. You can sign in with your GitHub ID to claim ownership of the project.The defect
Connection#process_requestreturns the params object unchanged when it is empty. TheClientandConnectionwrapper methods defaultparamsto{}, so for any non-GET verb that empty Hash is handed to Faraday as the request body, andNet::HTTPcallsbytesizeon it while framing the request —NoMethodError: undefined method 'bytesize' for {}:Hash, raised before a single byte is written to the socket.webhooks.delete(id),custom_fields.delete(id)andbroadcasts.delete(id)send no payload at all, so they raise on every call;tags.update(id)andsubscribers.update(id)do the same wheneveroptions.slice(...)comes back empty.tags.remove_from_subscriberescapes it only because it passes''as an explicit params argument rather than relying on the default.custom_fields.deleteandbroadcasts.deletehave a second problem on the same line: they call@client.delete(path)without asking for the raw response, soClient#handle_responsereturnsresponse.bodyandresponse.success?is then sent to a Hash. Their specs stub the client double as though it returned the response object, which is why the suite stayed green. Both now request the raw response the waytags.remove_from_subscriberalready does.Reproducing it on main
The failure needs a listening socket, because it happens while the body is framed, after the connection is opened. Against a local stub that reports the request line it received:
On
mainat a7c7d66:On this branch:
The change
lib/convertkit/connection.rb— an empty payload becomes'', which is exactly the bodytags.add_to_subscriber,tags.remove_from_subscriberandsubscribers.unsubscribealready send today, so nothing that currently works changes on the wire. A non-empty payload is stillJSON.generated, and GET params still pass through untouched.lib/convertkit/resources/custom_fields.rbandlib/convertkit/resources/broadcasts.rb— pass'', truesosuccess?is read off the Faraday response.Verification
main:bundle exec rspecgives 141 examples, 0 failures. On this branch: 144 examples, 0 failures — no test that passed before fails now.spec/lib/convertkit/connection_spec.rbpin the empty-payload request body fordelete,postandput, and the#deleteexamples incustom_fields_specandbroadcasts_specnow assert the raw-response contract. Reverting onlylib/while keeping the specs turns all five red (expected: "" got: {}, andreceived :delete with unexpected arguments), so they fail without the change and pass with it.trueand the DELETE actually arriving at the server, which the spec suite alone cannot show because it stubs the transport.How this was managed
This work was planned and tracked on a board imported from this repository's own pull requests and labels — 29 stories in all. The story behind this PR is Empty request payloads crash before the request is sent, and the board is at https://eastagiletracker.com/projects/493.
If you'd rather not receive contributions like this, reply
no-more-prson this pull request and we won't open any further ones on your repositories.Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com