Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem
When creating a rest resource that sends an sms using the module, the following exception appears when receiving a response from the resource:
A fatal error occurred: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\\rest\\ResourceResponse.
Solution
Similarly to how #2630808: Response::getResponse() does not collect cacheability metadata from Url object solved it, the Url generated should collect bubbleable metadata in SmsMessageProcessor::deliveryReportUrl()
.
Comment | File | Size | Author |
---|---|---|---|
#5 | TestSms.php_.txt | 880 bytes | nyariv |
#5 | rest.settings.yml | 129 bytes | nyariv |
#2 | 2790673-url_bubbleable_metadata.patch | 792 bytes | nyariv |
Comments
Comment #2
nyariv CreditAttribution: nyariv commentedComment #3
dpiCan you please post steps to reproduce? Linking to your own code if you desire, and providing instructions.
Can you supply tests with your patch.
Comment #4
dpiI also don't exactly understand why the SMS internals want to have anything to do with the caching system?
Comment #5
nyariv CreditAttribution: nyariv commented1) Copy attached resource class to [your_module]/src/Plugin/rest/resource. You will need to remove .txt from file name and change the namespace of the class to your module.
2) Enable core's rest module and import attached config
3) Enable permission 'Access GET on Test sms resource resource' for anonymous user
4) Do a GET request to
/test-sms/111?_format=json
it should say 'Sms sent' but instead it shows the exception error.I do not understand fully the source of the issue, but it has to do with Url caching.
Comment #6
nyariv CreditAttribution: nyariv commentedA workaround I found was to use
$response = new Response('Sms sent', 200);
instead of
$response = new ResourceResponse('Sms sent', 200);
which is a cacheable response. This only means my resource will not be cached.
Comment #7
nyariv CreditAttribution: nyariv commentedThis is for a module I am maintaining that sends verification codes through sms and heavily relies on sms framework. One of the features is to support verification through rest/services. I have committed the code with the above workaround, which is OK since I do not need caching anyways.
Would love your opinion,
https://www.drupal.org/project/mobile_number
Comment #8
dpiIm not sure if this is the same code in your module, its arguable whether you should be using GET for your resource?
I dont think you want to cache a send operation...?
I'll add it to my todo list :). What is the difference between the verification code system we are shipping with
sms_user
8.x, andmobile_number
?Comment #9
almaudoh CreditAttribution: almaudoh commentedI was able to replicate the behavior following #5. However, I'm not able to understand how
url->setAbsolute()->toString()
without capturing cacheability metadata ends up in arender
call outside a render context.Comment #10
almaudoh CreditAttribution: almaudoh commentedI'm also seeing an area where we can consolidate the functionalities of the two modules here.
Comment #11
nyariv CreditAttribution: nyariv commentedIndeed, a user of my module did report confusion about seeing an extra mobile number field in the user account page.
mobile_number is its own field type, and acts as a pivot to any integrations needed for a mobile number data type. So verification needs to be possible on any entity type that the field is added to, including also for use with two factor authentication. It would make sense to couple verification handling with the mobile number field and simplify smsframework to focus on simply being a provider for sending sms of any kind.
Because of TFA, verification codes need to receive a password-like treatment and expiration when storing them in the database. Perhaps verification codes need to be handled by a third module, but I am not aware of such a module so I created my own implementation.
When the send operation returns a verification token, which my module does, then caching is not desired.
I do use GET, perhaps you are right, POST would be more appropriate. I am having difficulties finding documentation for implementing a POST resource for rest though at the moment.
I would be more than happy to collaborate here and see how reuse can be done between the two modules.
Comment #12
dpiIf we are just discussing fields for a moment, then you would just need to integrate with Drupals' phone number module.
Dissecting mobile_number field:
\Drupal\sms\Entity\PhoneNumberVerification
.Obviously this is just my opinion, and I'm not familiar with the internals of the project.
Comment #13
nyariv CreditAttribution: nyariv commentedI tried integrating with phone module but it has it's own validation system which conflicts with mine so I was not able to do that. I explained here why mobile numbers should have it's own field type, plus the phone module is not actively maintained and they say on the project page to use 'telephone' module instead, which I can and have integrated with.
About the field properties:
If you have the time, install MB just to check it out, I am sure you could get some ideas for your own module. There are some limitations which prevented me from extending telephone like you did, like adding my own field constraints to telephone, or allowing users to select extensions to existing field types beyond just widget selection. I prefer to work with Drupal's intended api and avoid hackish ways to achieve these.
Comment #14
bradjones1The core of this issue report is basically #2638686: Exception in EarlyRenderingControllerWrapperSubscriber is a DX nightmare, remove it. The Url::toString() sets certain cacheable metadata, which "leaks" because it's not included in the cache metadata of the response you're ultimately building with your REST service. If the cacheable metadata you have on that response includes the metadata otherwise "leaked," you could be good to go, but it's not exactly predictable (e.g., it could depend on the logged-in user, etc... the cacheable properties of the link you're generating.)
I might have bungled the explanation a bit, but I wanted to relate this since it is pretty much the issue you're having, not necessarily specific to Sms module.