From 8f1c047cfe698d996e73e86a226127a14e503c9a Mon Sep 17 00:00:00 2001 From: Izaaz Yunus Date: Thu, 8 Aug 2024 16:36:17 -0700 Subject: [PATCH] fix: Fix OOM error when a bad api key is passed (#210) * fix: Fix OOM error when a bad api key is passed --- .../core/utilities/FileResponseHandler.kt | 2 +- .../core/utilities/InMemoryResponseHandler.kt | 2 +- .../com/amplitude/core/utilities/Response.kt | 4 ++ .../core/utilities/FileResponseHandlerTest.kt | 45 +++++++++++++++++++ .../utilities/InMemoryResponseHandlerTest.kt | 43 ++++++++++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 core/src/test/kotlin/com/amplitude/core/utilities/FileResponseHandlerTest.kt create mode 100644 core/src/test/kotlin/com/amplitude/core/utilities/InMemoryResponseHandlerTest.kt diff --git a/core/src/main/java/com/amplitude/core/utilities/FileResponseHandler.kt b/core/src/main/java/com/amplitude/core/utilities/FileResponseHandler.kt index ebbbd3ee..d7c0a2d9 100644 --- a/core/src/main/java/com/amplitude/core/utilities/FileResponseHandler.kt +++ b/core/src/main/java/com/amplitude/core/utilities/FileResponseHandler.kt @@ -65,7 +65,7 @@ class FileResponseHandler( removeCallbackByInsertId(eventsString) throw e } - if (eventsList.size == 1) { + if (eventsList.size == 1 || badRequestResponse.isInvalidApiKeyResponse()) { triggerEventsCallback(eventsList, HttpStatus.BAD_REQUEST.code, badRequestResponse.error) storage.removeFile(eventFilePath) return diff --git a/core/src/main/java/com/amplitude/core/utilities/InMemoryResponseHandler.kt b/core/src/main/java/com/amplitude/core/utilities/InMemoryResponseHandler.kt index 508ad16a..7d629a31 100644 --- a/core/src/main/java/com/amplitude/core/utilities/InMemoryResponseHandler.kt +++ b/core/src/main/java/com/amplitude/core/utilities/InMemoryResponseHandler.kt @@ -25,7 +25,7 @@ internal class InMemoryResponseHandler( override fun handleBadRequestResponse(badRequestResponse: BadRequestResponse, events: Any, eventsString: String) { val eventsList = events as List - if (eventsList.size == 1) { + if (eventsList.size == 1 || badRequestResponse.isInvalidApiKeyResponse()) { triggerEventsCallback(eventsList, HttpStatus.BAD_REQUEST.code, badRequestResponse.error) return } diff --git a/core/src/main/java/com/amplitude/core/utilities/Response.kt b/core/src/main/java/com/amplitude/core/utilities/Response.kt index fdad0f2a..ce1d41b1 100644 --- a/core/src/main/java/com/amplitude/core/utilities/Response.kt +++ b/core/src/main/java/com/amplitude/core/utilities/Response.kt @@ -91,6 +91,10 @@ class BadRequestResponse(response: JSONObject) : Response { return false } } + + fun isInvalidApiKeyResponse(): Boolean { + return error.lowercase().contains("invalid api key") + } } class PayloadTooLargeResponse(response: JSONObject) : Response { diff --git a/core/src/test/kotlin/com/amplitude/core/utilities/FileResponseHandlerTest.kt b/core/src/test/kotlin/com/amplitude/core/utilities/FileResponseHandlerTest.kt new file mode 100644 index 00000000..1d47c750 --- /dev/null +++ b/core/src/test/kotlin/com/amplitude/core/utilities/FileResponseHandlerTest.kt @@ -0,0 +1,45 @@ +package com.amplitude.core.utilities + +import com.amplitude.core.Configuration +import com.amplitude.core.events.BaseEvent +import com.amplitude.core.platform.EventPipeline +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.json.JSONObject +import org.junit.jupiter.api.Test + +class FileResponseHandlerTest { + @Test + fun testBadResponseHandlerForInvalidApiKey() { + val response = BadRequestResponse( + JSONObject("{\"error\":\"Invalid API key\"}") + ) + val storage = mockk() + val pipeline = mockk() + val handler = + FileResponseHandler(storage, pipeline, Configuration("test"), mockk(), mockk(), null) + + every { + storage.removeFile("file_path") + } returns true + + handler.handleBadRequestResponse( + response, + "file_path", + JSONUtil.eventsToString( + listOf(generateBaseEvent("test1"), generateBaseEvent("test2")) + ) + ) + + verify(exactly = 1) { + storage.removeFile("file_path") + } + } + + private fun generateBaseEvent(eventType: String): BaseEvent { + val baseEvent = BaseEvent() + baseEvent.eventType = eventType + return baseEvent + } +} diff --git a/core/src/test/kotlin/com/amplitude/core/utilities/InMemoryResponseHandlerTest.kt b/core/src/test/kotlin/com/amplitude/core/utilities/InMemoryResponseHandlerTest.kt new file mode 100644 index 00000000..7305e6a5 --- /dev/null +++ b/core/src/test/kotlin/com/amplitude/core/utilities/InMemoryResponseHandlerTest.kt @@ -0,0 +1,43 @@ +package com.amplitude.core.utilities + +import com.amplitude.core.Configuration +import com.amplitude.core.events.BaseEvent +import com.amplitude.core.platform.EventPipeline +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.json.JSONObject +import org.junit.jupiter.api.Test + +class InMemoryResponseHandlerTest { + @Test + fun testBadResponseHandlerForInvalidApiKey() { + val response = BadRequestResponse( + JSONObject("{\"error\":\"Invalid API key\"}") + ) + val storage = mockk() + val pipeline = mockk() + val handler = + InMemoryResponseHandler(pipeline, Configuration("test"), mockk(), mockk()) + + every { + storage.removeFile("file_path") + } returns true + + handler.handleBadRequestResponse( + response, + listOf(generateBaseEvent("test1"), generateBaseEvent("test2")), + "" + ) + + verify(exactly = 0) { + pipeline.put(any()) + } + } + + private fun generateBaseEvent(eventType: String): BaseEvent { + val baseEvent = BaseEvent() + baseEvent.eventType = eventType + return baseEvent + } +}