Skip to content

Commit 701e6cd

Browse files
committed
fix: Correct exception handling for CloudEvents
A previous change resulted broke exception handling for cloud events so that an exception from the function would not result in a failure response code. Correct error handling for CloudEvents and add a test to cover this case to avoid future breakages.
1 parent d6f7186 commit 701e6cd

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,7 @@ private <CloudEventT> void serviceCloudEvent(HttpServletRequest req) throws Exce
364364
// ServiceLoader.load
365365
// will throw ServiceConfigurationError. At this point we're still running with the default
366366
// context ClassLoader, which is the system ClassLoader that has loaded the code here.
367-
try {
368-
executionIdUtil.storeExecutionId(req);
369-
runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data)));
370-
} catch (Throwable t) {
371-
logger.log(Level.SEVERE, "Failed to execute " + executor.functionName(), t);
372-
} finally {
373-
executionIdUtil.removeExecutionId();
374-
}
367+
runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data)));
375368
// The data->data is a workaround for a bug fixed since Milestone 4 of the SDK, in
376369
// https://github.com/cloudevents/sdk-java/pull/259.
377370
}

invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,43 @@ public void nativeCloudEvent() throws Exception {
577577
ImmutableList.of(cloudEventsStructuredTestCase, cloudEventsBinaryTestCase));
578578
}
579579

580+
/** Tests a CloudEvent being handled by a CloudEvent handler throws exception */
581+
@Test
582+
public void nativeCloudEventException() throws Exception {
583+
String exceptionExpectedOutput =
584+
"\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":"
585+
+ " \"com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java\", \"method\":"
586+
+ " \"service\"}, \"execution_id\": \""
587+
+ EXECUTION_ID
588+
+ "\", "
589+
+ "\"message\": \"Failed to execute"
590+
+ " com.google.cloud.functions.invoker.testfunctions.ExceptionBackground\\n"
591+
+ "java.lang.RuntimeException: exception thrown for test";
592+
File snoopFile = snoopFile();
593+
CloudEvent cloudEvent = sampleCloudEvent(snoopFile);
594+
EventFormat jsonFormat =
595+
EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE);
596+
String cloudEventJson = new String(jsonFormat.serialize(cloudEvent), UTF_8);
597+
598+
// A CloudEvent using the "structured content mode", where both the metadata and the payload
599+
// are in the body of the HTTP request.
600+
TestCase cloudEventsStructuredTestCase =
601+
TestCase.builder()
602+
.setRequestText(cloudEventJson)
603+
.setHttpContentType("application/cloudevents+json; charset=utf-8")
604+
.setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID))
605+
.setExpectedResponseCode(500)
606+
.setExpectedOutput(exceptionExpectedOutput)
607+
.build();
608+
609+
testFunction(
610+
SignatureType.CLOUD_EVENT,
611+
fullTarget("ExceptionBackground"),
612+
ImmutableList.of(),
613+
ImmutableList.of(cloudEventsStructuredTestCase),
614+
Collections.emptyMap());
615+
}
616+
580617
@Test
581618
public void nested() throws Exception {
582619
String testText = "sic transit gloria mundi";

0 commit comments

Comments
 (0)