Skip pixels without an access token instead of rejecting the whole event - #19
Merged
Merged
Conversation
Since #17 a single pixel without an access token made the client throw before sending anything, so that one pixel kept every other pixel from receiving the event. A pixel without an access token is a legitimate state, a pixel that is only used in the browser for instance, so a shop with one such pixel next to fully configured ones got no server events at all. The client now sends to every pixel that has an access token, skips the ones that do not, and logs an error naming them. It throws an InvalidArgumentException only when none of the pixels has an access token, which is what happens when PreparedEvent::withAccessTokens() is forgotten after withoutAccessTokens(): then nothing can be delivered and it is almost certainly a mistake. A request without an access token is still never made, since Meta answers it with an error that does not mention the token.
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.
Summary
Since #17 a single pixel without an access token made the client throw before sending anything. That caught a forgotten
withAccessTokens(), but it also meant one token-less pixel kept every other pixel from receiving the event. And a token-less pixel is a documented, legitimate state: the docblock onPixel::$accessTokenlists browser-only tracking as the first reason the token is nullable. A shop with one browser-only pixel next to three fully configured ones got no server events at all.Behaviour now
The event was not sent to these pixels because they have no access token: pixel_2, pixel_4.InvalidArgumentExceptiononly when none of the pixels has an access token. That is what a forgottenPreparedEvent::withAccessTokens()afterwithoutAccessTokens()looks like, since then every pixel is token-less. Nothing can be delivered, so failing loudly is right, and no request is made.This lines up with how the client already treats an event with no pixels at all: a log line, not an exception.
The trade-off
If a pixel id is missing from the map passed to
withAccessTokens(), that pixel is now skipped with an error log instead of stopping everything. The other pixels still get their conversions, and the log names the pixel. A consumer that wants strictness can check the pixels before sending.Not in this PR
The same principle is violated elsewhere: when Meta answers non-200 for one pixel, the loop throws immediately, so pixels after it never receive the event while pixels before it already have. Attempting all pixels and reporting failures at the end is a bigger change and deserves its own discussion.
Compatibility
No BC break (Roave: none). Relative to
v2.0.0-alpha.2this relaxes behaviour: a mix of pixels with and without access tokens no longer throws.Docs
README (queue section, the
InvalidArgumentExceptionrow in the error handling table, the logging section), CLAUDE.md,UPGRADE-2.0.md(section rewritten: "Pixels without an access token are skipped"), and the docblocks onClientInterface,Pixel::$accessTokenandInvalidArgumentException.Test plan
it_skips_the_pixels_without_an_access_token_and_sends_to_the_others— four pixels, one browser-only and one with an empty token: exactly the other two receive the event with their own tokens, and exactly one error is logged naming the skipped twoit_throws_when_none_of_the_pixels_has_an_access_token—prepare()->withoutAccessTokens()sent as is: the message lists the pixels, no request madeit_treats_an_empty_access_token_as_missing— unchanged, still throws for a single pixelit_logs_nothing_when_all_pixels_have_an_access_token2.x: no breaks