@W-22607468: [MSDK Android] Using application/json Content Header For Actionable Notification Action Submission With Empty Request Body Causes Endpoint Errors#2900
Conversation
…or Actionable Notification Action Submission With Empty Request Body Causes Endpoint Errors
| POST, | ||
| "https://${restClient.clientInfo.instanceUrl.host}/${ApiVersionStrings.getBasePath()}/connect/notifications/${notificationId}/actions/${actionKey}", | ||
| "".toRequestBody(MEDIA_TYPE_JSON), | ||
| ByteArray(0).toRequestBody(MEDIA_TYPE_FORM_URLENCODED), |
There was a problem hiding this comment.
A subtle hint from the code review tools was to use the empty byte array so future reviews won't see the content type and string as a mismatch.
There was a problem hiding this comment.
Why does it need an empty body at all?
There was a problem hiding this comment.
I was sure I remembered plus the code review tools were pretty sure as well: Our third-party networking library has a hard rule that POST requests must have a non-null body. There's an unsafe constructor for RestRequest that had tripped this up when I first built the actionable notifications client:
public RestRequest(RestMethod method, String path, Map<String, String> additionalHttpHeaders) {
this(method, path, (RequestBody) null, additionalHttpHeaders);
}
When method is POST a null requestBody triggers this exception.
2026-05-22 00:09:14.517 6622-6667 AndroidNat...inTemplate com.salesforce.androidnativekotlin E Failed to invoke notification action
java.lang.IllegalArgumentException: method POST must have a request body.
at okhttp3.Request$Builder.method(Request.kt:341)
at com.salesforce.androidsdk.rest.RestClient.buildRequest(RestClient.java:333)
at com.salesforce.androidsdk.rest.RestClient.sendSync(RestClient.java:391)
at com.salesforce.androidsdk.rest.NotificationsApiClient.submitNotificationAction(NotificationsApiClient.kt:112)
at com.salesforce.androidsdk.app.SalesforceSDKManager.invokeServerNotificationAction(SalesforceSDKManager.kt:751)
at com.salesforce.androidsdk.app.SalesforceSDKManager.invokeServerNotificationAction$default(SalesforceSDKManager.kt:744)
at com.salesforce.androidnativekotlin.MainApplication$InvokeNotificationActionBroadcastIntentReceiver$onReceive$1.invokeSuspend(MainApplication.kt:229)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:101)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:832)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707)
So it seems we still need the non-null empty request body for this POST request. Good question, 'cuz I'd asked the same when I first tried it 😆
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (50.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## dev #2900 +/- ##
============================================
- Coverage 55.17% 55.01% -0.16%
+ Complexity 2509 2504 -5
============================================
Files 226 226
Lines 17781 17774 -7
Branches 2328 2327 -1
============================================
- Hits 9810 9778 -32
- Misses 6966 6993 +27
+ Partials 1005 1003 -2
🚀 New features to boost your workflow:
|
…on submissions Directly tests NotificationsApiClient.submitNotificationAction to assert the request body uses application/x-www-form-urlencoded with zero-length content, ensuring coverage of lines 106-112.
🎸 Ready For Review 🥁
This simple update changes the content type header for actionable notifications action submission requests to the one the endpoint expects.