Skip to content

Commit b1fddf9

Browse files
Fix JsonToRow swallowing downstream errors when runners fuse transforms.
Separate JSON parsing from MultiOutputReceiver output in ParseWithError so exceptions from fused downstream consumers are not misreported as parse failures. Fixes #20935. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1cadc5f commit b1fddf9

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/JsonToRow.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,10 @@ public static ParseWithError create(JsonToRowWithErrFn jsonToRowWithErrFn) {
309309

310310
@ProcessElement
311311
public void processElement(@Element String element, MultiOutputReceiver output) {
312+
final Row parsedRow;
312313
try {
313-
314-
output.get(PARSED_LINE).output(jsonToRow(objectMapper(), element));
315-
314+
parsedRow = jsonToRow(objectMapper(), element);
316315
} catch (Exception ex) {
317-
318316
if (getJsonToRowWithErrFn().getExtendedErrorInfo()) {
319317
output
320318
.get(PARSE_ERROR)
@@ -328,7 +326,9 @@ public void processElement(@Element String element, MultiOutputReceiver output)
328326
.get(PARSE_ERROR)
329327
.output(Row.withSchema(ERROR_ROW_SCHEMA).addValue(element).build());
330328
}
329+
return;
331330
}
331+
output.get(PARSED_LINE).output(parsedRow);
332332
}
333333

334334
private ObjectMapper objectMapper() {

sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/JsonToRowTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,31 @@ public void testParsesErrorWithErrorMsgWithRequireNullDeadLetter() throws Except
274274
pipeline.run();
275275
}
276276

277+
@Test
278+
@Category(NeedsRunner.class)
279+
public void testDownstreamExceptionIsNotReportedAsParseError() {
280+
PCollection<String> jsonPersons = pipeline.apply("jsonPersons", Create.of(JSON_PERSON.get(0)));
281+
282+
ParseResult results = jsonPersons.apply(JsonToRow.withExceptionReporting(PERSON_SCHEMA));
283+
284+
results
285+
.getResults()
286+
.apply(
287+
"throwingDownstream",
288+
ParDo.of(
289+
new DoFn<Row, Row>() {
290+
@ProcessElement
291+
public void processElement(ProcessContext context) {
292+
throw new RuntimeException("downstream failure");
293+
}
294+
}));
295+
296+
thrown.expect(RuntimeException.class);
297+
thrown.expectMessage("downstream failure");
298+
299+
pipeline.run();
300+
}
301+
277302
@Test
278303
@Category(NeedsRunner.class)
279304
public void testParsesErrorWithErrorMsgRowsDeadLetterWithCustomFieldNames() throws Exception {

0 commit comments

Comments
 (0)