From f7338addfbcbd33f31a80331018b68035ae0ce07 Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:12:19 +0200 Subject: [PATCH 1/7] Implement an interface for functions that need to handle failures. I took a more OOP approach for this feature which is slightly different than the other SDKs but we can discuss this further in the PR review. The `WithFailureHandler` interface has a single method `onFailure` that is called when the function fails. An example of how to use this: ```kotlin class MyFunction : InngestFunction(), WithFailureHandler { override fun execute(ctx: FunctionContext, step: Step): Any? { // Do something } override fun onFailure(ctx: FunctionContext, step: Step): Any? { // Handle failure } } ``` --- inngest/src/main/kotlin/com/inngest/Comm.kt | 14 +++++++++++++- .../kotlin/com/inngest/InngestFunction.kt | 19 ++++++++++++++++++- .../inngest/InngestFunctionConfigBuilder.kt | 2 +- .../kotlin/com/inngest/WithFailureHandler.kt | 14 ++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt diff --git a/inngest/src/main/kotlin/com/inngest/Comm.kt b/inngest/src/main/kotlin/com/inngest/Comm.kt index d1d4251b..3d733807 100644 --- a/inngest/src/main/kotlin/com/inngest/Comm.kt +++ b/inngest/src/main/kotlin/com/inngest/Comm.kt @@ -54,6 +54,15 @@ data class CommError( private val stepTerminalStatusCodes = setOf(ResultStatusCode.StepComplete, ResultStatusCode.StepError) +private fun generateFailureFunctions( + functions: Map, + client: Inngest, +): Map = + functions + .mapNotNull { (_, fn) -> + fn.toFailureHandler(client.appId)?.let { it.id()!! to it } + }.toMap() + class CommHandler( functions: Map, val client: Inngest, @@ -61,7 +70,10 @@ class CommHandler( private val framework: SupportedFrameworkName, ) { val headers = Environment.inngestHeaders(framework).plus(client.headers) - private val functions = functions.mapValues { (_, fn) -> fn.toInngestFunction() } + private val functions = + functions + .mapValues { (_, fn) -> fn.toInngestFunction() } + .plus(generateFailureFunctions(functions, client)) fun callFunction( functionId: String, diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt index a64dc6ab..18766fd2 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt @@ -1,5 +1,7 @@ package com.inngest +const val FUNCTION_FAILED = "inngest/function.failed" + abstract class InngestFunction { open fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder = builder @@ -29,5 +31,20 @@ abstract class InngestFunction { return InternalInngestFunction(configBuilder, this::execute) } - // TODO - Add toFailureHandler method to generate a second function if configured + internal fun toFailureHandler(appId: String): InternalInngestFunction? { + if (this is WithFailureHandler) { + val fnConfig = buildConfig() + val fullyQualifiedId = "$appId-${fnConfig.id}" + val fnName = fnConfig.name ?: fnConfig.id + + val configBuilder = + InngestFunctionConfigBuilder() + .id("${fnConfig.id}-failure") + .name("$fnName (failure)") + .triggerEventIf(FUNCTION_FAILED, "event.data.function_id == '$fullyQualifiedId'") + + return InternalInngestFunction(configBuilder, this::onFailure) + } + return null + } } diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt index 04b480f6..e6b06da5 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt @@ -9,7 +9,7 @@ import java.time.Duration // TODO: Throw illegal argument exception class InngestFunctionConfigBuilder { var id: String? = null - private var name: String? = null + var name: String? = null private var triggers: MutableList = mutableListOf() private var concurrency: MutableList? = null private var retries = 3 diff --git a/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt b/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt new file mode 100644 index 00000000..c154a910 --- /dev/null +++ b/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt @@ -0,0 +1,14 @@ +package com.inngest + +interface WithFailureHandler { + /** + * Function to call when the Inngest function fails. + * + * @param ctx The function context including event(s) that triggered the function + * @param step A class with methods to define steps within the function + */ + fun onFailure( + ctx: FunctionContext, + step: Step, + ): Any? +} From 080d8ac8e0ec6bde2ba7a6cf7d673cc7f9105077 Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:17:19 +0200 Subject: [PATCH 2/7] Add a function with an onFailure handler and a test for it --- .../springbootdemo/DevServerComponent.java | 8 +++ .../springbootdemo/EventsResponse.java | 39 ++++++++++++ .../testfunctions/WithOnFailureFunction.java | 31 ++++++++++ .../springbootdemo/DemoTestConfiguration.java | 1 + .../WithOnFailureIntegrationTest.java | 62 +++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventsResponse.java create mode 100644 inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java create mode 100644 inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java index d61d8d04..272c0abf 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DevServerComponent.java @@ -55,6 +55,14 @@ EventRunsResponse runsByEvent(String eventId) throws Exception { }); } + EventsResponse listEvents() throws Exception { + Request request = new Request.Builder() + .url(String.format("%s/v1/events", baseUrl)) + .build(); + return makeRequest(request, new TypeReference() { + }); + } + RunResponse runById(String eventId, Class outputType) throws Exception { Request request = new Request.Builder() .url(String.format("%s/v1/runs/%S", baseUrl, eventId)) diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventsResponse.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventsResponse.java new file mode 100644 index 00000000..7cde30ed --- /dev/null +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/EventsResponse.java @@ -0,0 +1,39 @@ +package com.inngest.springbootdemo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class EventsResponse { + EventEntry[] data; +} + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class EventEntry { + String id; + String name; + + String internal_id; + + EventEntryData data; +} + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class EventEntryData{ + EventData event; +} + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +class EventData { + String name; +} + diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java new file mode 100644 index 00000000..6d2e6d72 --- /dev/null +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java @@ -0,0 +1,31 @@ +package com.inngest.springbootdemo.testfunctions; + +import com.inngest.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class WithOnFailureFunction extends InngestFunction implements WithFailureHandler { + @NotNull + @Override + public InngestFunctionConfigBuilder config(InngestFunctionConfigBuilder builder) { + return builder + .id("with-on-failure-function") + .name("With On Failure Function") + .triggerEvent("test/with-on-failure"); + } + + @Override + public String execute(FunctionContext ctx, Step step) { + step.run("fail-step", () -> { + throw new NonRetriableError("something fatally went wrong"); + }, String.class); + + return "Success"; + } + + @Nullable + @Override + public String onFailure(@NotNull FunctionContext ctx, @NotNull Step step) { + return "On Failure Success"; + } +} diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java index cbada3ea..cff6a8c3 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java @@ -29,6 +29,7 @@ protected HashMap functions() { addInngestFunction(functions, new IdempotentFunction()); addInngestFunction(functions, new Scale2DObjectFunction()); addInngestFunction(functions, new MultiplyMatrixFunction()); + addInngestFunction(functions, new WithOnFailureFunction()); return functions; } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java new file mode 100644 index 00000000..c45792f1 --- /dev/null +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java @@ -0,0 +1,62 @@ +package com.inngest.springbootdemo; + +import com.inngest.CommHandler; +import com.inngest.Inngest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@IntegrationTest +@Execution(ExecutionMode.CONCURRENT) +class WithOnFailureIntegrationTest { + @BeforeAll + static void setup(@Autowired CommHandler handler) { + handler.register("http://localhost:8080"); + } + + @Autowired + private DevServerComponent devServer; + + static int sleepTime = 5000; + + @Autowired + private Inngest client; + + @Test + void testWithOnFailureShouldCallOnFailure() throws Exception { + String eventName = "test/with-on-failure"; + String eventId = InngestFunctionTestHelpers.sendEvent(client, eventName).first(); + + Thread.sleep(sleepTime); + + // Check that the original function failed + RunEntry run = devServer.runsByEvent(eventId).first(); + LinkedHashMap output = (LinkedHashMap) run.getOutput(); + + assertEquals("Failed", run.getStatus()); + assertNotNull(run.getEnded_at()); + assert output.get("name").contains("NonRetriableError"); + + // Check that the onFailure function was called + Optional event = Arrays.stream(devServer.listEvents().getData()) + .filter(e -> "inngest/function.failed".equals(e.getName()) && eventName.equals(e.getData().getEvent().getName())) + .findFirst(); + + assert event.isPresent(); + + RunEntry onFailureRun = devServer.runsByEvent(event.get().getInternal_id()).first(); + + assertEquals("Completed", onFailureRun.getStatus()); + assertEquals("On Failure Success", (String) onFailureRun.getOutput()); + } +} From 861ef1f6b567cb5f95fde04d52396132bb8e1eb2 Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:18:06 +0200 Subject: [PATCH 3/7] Add a Kotlin function example that has a failure handler --- .../main/kotlin/com/inngest/testserver/App.kt | 1 + .../inngest/testserver/SlackFailureReport.kt | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt diff --git a/inngest-test-server/src/main/kotlin/com/inngest/testserver/App.kt b/inngest-test-server/src/main/kotlin/com/inngest/testserver/App.kt index 5e947fd1..d0bb969d 100644 --- a/inngest-test-server/src/main/kotlin/com/inngest/testserver/App.kt +++ b/inngest-test-server/src/main/kotlin/com/inngest/testserver/App.kt @@ -29,6 +29,7 @@ fun Application.module() { TranscodeVideo(), ImageFromPrompt(), PushToSlackChannel(), + SlackFailureReport(), WeeklyCleanup(), ), ) diff --git a/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt b/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt new file mode 100644 index 00000000..dff8684b --- /dev/null +++ b/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt @@ -0,0 +1,36 @@ +package com.inngest.testserver + +import com.inngest.* + +class SlackFailureReport : + InngestFunction(), + WithFailureHandler { + override fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder = + builder + .id("always-fail-fn") + .name("Always Fail Function") + .triggerEvent("always-fail-fn") + + override fun execute( + ctx: FunctionContext, + step: Step, + ): String { + step.run("throw exception") { + throw RuntimeException("This function always fails") + "Step result" + } + + return "Success" + } + + override fun onFailure( + ctx: FunctionContext, + step: Step, + ): String { + step.run("send slack message") { + "Sending a message to Slack" + } + + return "onFailure Success" + } +} From cb8582d275b3fc840bebc92240045defe3b42500 Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:24:00 +0200 Subject: [PATCH 4/7] Make name in InngestFunctionConfigBuilder internal --- .../src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt index e6b06da5..0debb43f 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt @@ -9,7 +9,7 @@ import java.time.Duration // TODO: Throw illegal argument exception class InngestFunctionConfigBuilder { var id: String? = null - var name: String? = null + internal var name: String? = null private var triggers: MutableList = mutableListOf() private var concurrency: MutableList? = null private var retries = 3 From de78a21cb7456fead97e5600b190e7bea5623607 Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Tue, 10 Sep 2024 22:43:34 +0200 Subject: [PATCH 5/7] Run formatting --- inngest/src/main/kotlin/com/inngest/InngestFunction.kt | 4 +--- .../kotlin/com/inngest/InngestFunctionConfigBuilder.kt | 10 ++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt index 18766fd2..81b9119f 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt @@ -21,9 +21,7 @@ abstract class InngestFunction { return this.config(builder) } - fun id(): String { - return buildConfig().id!! - } + fun id(): String = buildConfig().id!! internal fun toInngestFunction(): InternalInngestFunction { val builder = InngestFunctionConfigBuilder() diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt index 0debb43f..f4b136ae 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunctionConfigBuilder.kt @@ -115,8 +115,14 @@ class InngestFunctionConfigBuilder { scope: ConcurrencyScope? = null, ): InngestFunctionConfigBuilder { when (scope) { - ConcurrencyScope.ENVIRONMENT -> if (key == null) throw InngestInvalidConfigurationException("Concurrency key required with environment scope") - ConcurrencyScope.ACCOUNT -> if (key == null) throw InngestInvalidConfigurationException("Concurrency key required with account scope") + ConcurrencyScope.ENVIRONMENT -> + if (key == null) { + throw InngestInvalidConfigurationException("Concurrency key required with environment scope") + } + ConcurrencyScope.ACCOUNT -> + if (key == null) { + throw InngestInvalidConfigurationException("Concurrency key required with account scope") + } ConcurrencyScope.FUNCTION -> {} null -> {} } From 46b23235a518450d1bd8b302be3408f217e5427b Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Tue, 10 Sep 2024 23:35:47 +0200 Subject: [PATCH 6/7] Switch to an overridable `onFailure` method in `InngestFunction` This removes the `WithFailureHandler` interface and instead provides an overridable `onFailure` method in `InngestFunction` that can be used to define a function to be called when the function fails. It's used in the same way but without the need to implement an interface ```kotlin class MyFunction : InngestFunction() { override fun execute(ctx: FunctionContext, step: Step): Any? { // Do something } override fun onFailure(ctx: FunctionContext, step: Step): Any? { // Handle failure } } ``` --- .../testfunctions/WithOnFailureFunction.java | 2 +- .../WithOnFailureIntegrationTest.java | 7 +------ .../inngest/testserver/SlackFailureReport.kt | 4 +--- .../kotlin/com/inngest/InngestFunction.kt | 20 ++++++++++++++++++- .../kotlin/com/inngest/WithFailureHandler.kt | 14 ------------- 5 files changed, 22 insertions(+), 25 deletions(-) delete mode 100644 inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java index 6d2e6d72..4e9825db 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/testfunctions/WithOnFailureFunction.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class WithOnFailureFunction extends InngestFunction implements WithFailureHandler { +public class WithOnFailureFunction extends InngestFunction { @NotNull @Override public InngestFunctionConfigBuilder config(InngestFunctionConfigBuilder builder) { diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java index c45792f1..6a9647d7 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WithOnFailureIntegrationTest.java @@ -19,11 +19,6 @@ @IntegrationTest @Execution(ExecutionMode.CONCURRENT) class WithOnFailureIntegrationTest { - @BeforeAll - static void setup(@Autowired CommHandler handler) { - handler.register("http://localhost:8080"); - } - @Autowired private DevServerComponent devServer; @@ -35,7 +30,7 @@ static void setup(@Autowired CommHandler handler) { @Test void testWithOnFailureShouldCallOnFailure() throws Exception { String eventName = "test/with-on-failure"; - String eventId = InngestFunctionTestHelpers.sendEvent(client, eventName).first(); + String eventId = InngestFunctionTestHelpers.sendEvent(client, eventName).getIds()[0]; Thread.sleep(sleepTime); diff --git a/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt b/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt index dff8684b..e0ed2ef5 100644 --- a/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt +++ b/inngest-test-server/src/main/kotlin/com/inngest/testserver/SlackFailureReport.kt @@ -2,9 +2,7 @@ package com.inngest.testserver import com.inngest.* -class SlackFailureReport : - InngestFunction(), - WithFailureHandler { +class SlackFailureReport : InngestFunction() { override fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder = builder .id("always-fail-fn") diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt index 81b9119f..f116dcdc 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt @@ -30,7 +30,9 @@ abstract class InngestFunction { } internal fun toFailureHandler(appId: String): InternalInngestFunction? { - if (this is WithFailureHandler) { + val onFailureMethod = this.javaClass.getMethod("onFailure", FunctionContext::class.java, Step::class.java) + + if (onFailureMethod.declaringClass != InngestFunction::class.java) { val fnConfig = buildConfig() val fullyQualifiedId = "$appId-${fnConfig.id}" val fnName = fnConfig.name ?: fnConfig.id @@ -45,4 +47,20 @@ abstract class InngestFunction { } return null } + + /** + * Provide a function to be called if your function fails, meaning + * that it ran out of retries and was unable to complete successfully. + * + * This is useful for sending warning notifications or cleaning up + * after a failure and supports all the same functionality as a + * regular handler. + * + * @param ctx The function context including event(s) that triggered the function + * @param step A class with methods to define steps within the function + */ + open fun onFailure( + ctx: FunctionContext, + step: Step, + ): Any? = null } diff --git a/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt b/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt deleted file mode 100644 index c154a910..00000000 --- a/inngest/src/main/kotlin/com/inngest/WithFailureHandler.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.inngest - -interface WithFailureHandler { - /** - * Function to call when the Inngest function fails. - * - * @param ctx The function context including event(s) that triggered the function - * @param step A class with methods to define steps within the function - */ - fun onFailure( - ctx: FunctionContext, - step: Step, - ): Any? -} From d8d9b2305978ae65673808201084b1ec2b85cfbd Mon Sep 17 00:00:00 2001 From: Riadh <22998716+KiKoS0@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:42:13 +0200 Subject: [PATCH 7/7] Address PR comments related to code clarity --- inngest/src/main/kotlin/com/inngest/Comm.kt | 7 +++---- inngest/src/main/kotlin/com/inngest/InngestFunction.kt | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inngest/src/main/kotlin/com/inngest/Comm.kt b/inngest/src/main/kotlin/com/inngest/Comm.kt index 3d733807..e27e3cc2 100644 --- a/inngest/src/main/kotlin/com/inngest/Comm.kt +++ b/inngest/src/main/kotlin/com/inngest/Comm.kt @@ -70,10 +70,9 @@ class CommHandler( private val framework: SupportedFrameworkName, ) { val headers = Environment.inngestHeaders(framework).plus(client.headers) - private val functions = - functions - .mapValues { (_, fn) -> fn.toInngestFunction() } - .plus(generateFailureFunctions(functions, client)) + + private val failureFunctions = generateFailureFunctions(functions, client) + private val functions = functions.mapValues { (_, fn) -> fn.toInngestFunction() }.plus(failureFunctions) fun callFunction( functionId: String, diff --git a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt index f116dcdc..64bb733a 100644 --- a/inngest/src/main/kotlin/com/inngest/InngestFunction.kt +++ b/inngest/src/main/kotlin/com/inngest/InngestFunction.kt @@ -32,6 +32,7 @@ abstract class InngestFunction { internal fun toFailureHandler(appId: String): InternalInngestFunction? { val onFailureMethod = this.javaClass.getMethod("onFailure", FunctionContext::class.java, Step::class.java) + // Only generate the failure handler if the onFailure method was overridden if (onFailureMethod.declaringClass != InngestFunction::class.java) { val fnConfig = buildConfig() val fullyQualifiedId = "$appId-${fnConfig.id}"