Skip to content

Logging the fieldName in the coerce exceptions #14483

Merged
abhishekagarwal87 merged 2 commits into
apache:masterfrom
pranavbhole:improvedLoggingIn_Coerce
Jul 3, 2023
Merged

Logging the fieldName in the coerce exceptions #14483
abhishekagarwal87 merged 2 commits into
apache:masterfrom
pranavbhole:improvedLoggingIn_Coerce

Conversation

@pranavbhole
Copy link
Copy Markdown
Contributor

@pranavbhole pranavbhole commented Jun 24, 2023

Description

This PR is improving the logging in coerce exceptions, coerce is currently eating some exceptions esp on JSON and primitive array parsing. This change is adding the exceptions in suppressed. Somehow in ingestion flow, we are getting the Value in coerce as new byte[0] with SqlType BIGINT which is throwing the following exceptions.
Error: Unknown exception Cannot coerce [[B] to BIGINT

People had hard time in finding out which field is causing the exception while querying. Thus, this change is logging the fieldName along with exception. This will help us identify the issues in the ingestion and we can figure why are we ingesting primitive arrays.

Fixed the bug ...

Renamed the class ...

Added a forbidden-apis entry ...

Release note


Key changed/added classes in this PR
  • MyFoo
  • OurBar
  • TheirBaz

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.
  • added or updated version, license, or notice information in licenses.yaml
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • added integration tests.
  • been tested in a test Druid cluster.

Copy link
Copy Markdown
Contributor

@LakshSingla LakshSingla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

Can you add a SQL test (CalciteQueryTest) and/or an MSQ query that shows the coercion error

public void testCoerceOfArrayOfPrimitives()
{
try {
ObjectMapper mapper = new ObjectMapper();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we should initialize this outside the test case since it would assist any other tests trying to use an object mapper.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ObjectMapper mapper = new ObjectMapper();
ObjectMapper mapper = new DefaultObjectMapper();

While it might not affect this use case, DefaultObjectMapper() is preferred since it contains Druid's modules having custom serdes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

private static String prepareCoerceException(Object value, SqlTypeName sqlTypeName, String fieldName)
{
return StringUtils.format(
"Cannot coerce field [%s] of value with class [%s] to %s",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Cannot coerce field [%s] of value with class [%s] to %s",
"Cannot coerce field [%s] of value with class [%s] to [%s]",

Copy link
Copy Markdown
Contributor

@zachjsh zachjsh Jun 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Cannot coerce field [%s] of type [%s] to type [%s]"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


private static ISE coerceExceptionWithSupressed(Object value, SqlTypeName sqlTypeName, String fieldName, Throwable t)
{
ISE e = new ISE(prepareCoerceException(value, sqlTypeName, fieldName));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the newly added DruidException class since it's a using-facing message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

private static ISE coerceExceptionWithSupressed(Object value, SqlTypeName sqlTypeName, String fieldName, Throwable t)
{
ISE e = new ISE(prepareCoerceException(value, sqlTypeName, fieldName));
e.addSuppressed(t);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not very clear with the semantics of adding t as suppressed v/s adding it as a cause.
Since t is directly causing the coercion exception that we are raising, I suppose it should be a cause. right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the new DruidExceptions

Assert.fail("Should throw an exception");
}
catch (Exception e) {
Assert.assertEquals("Cannot coerce field [testFieldName] of value with class [[B] to BIGINT", e.getMessage());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also more friendly type names such as binary instead of [[B?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add the mapping of primitive array class names to actual names. Following list is standard to Strings for primitive java arrays classnames.
[Z = boolean
[B = byte
[S = short
[I = int
[J = long
[F = float
[D = double
[C = char
[L = any non-primitives(Object)

@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch 2 times, most recently from f9a6840 to ec7687c Compare June 28, 2023 00:18
@pranavbhole
Copy link
Copy Markdown
Contributor Author

Thanks for the PR!

Can you add a SQL test (CalciteQueryTest) and/or an MSQ query that shows the coercion error

Coerce error happens while indexing the hll sketch columns with empty values. test framework was not ingesting it as correct long values and I was not able to add test that has byte array in the ingestions.

@pranavbhole
Copy link
Copy Markdown
Contributor Author

@LakshSingla @abhishekagarwal87 Can you please review?

@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch 2 times, most recently from 5f6cc9b to ea6a82c Compare June 28, 2023 21:34
Assert.fail("Should throw an exception");
}
catch (Exception e) {
Assert.assertEquals("Cannot coerce field [fieldName] class of [[B] to [BIGINT]", e.getMessage());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weren't we going to replace [[B] with a more friendly name such as binary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added mapping

t,
"Cannot coerce field [%s] class of [%s] to [%s]",
fieldName,
value == null ? "null" : value.getClass().getName(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value == null ? "null" : value.getClass().getName(),
value == null ? "unknown" : value.getClass().getName(),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

)
{
return new ISE(t, "Cannot coerce [%s] to [%s]", value == null ? "null" : value.getClass().getName(), sqlTypeName);
return DruidException.forPersona(DruidException.Persona.DEVELOPER)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I would say that this is for user persona since its an invalid input.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

.ofCategory(DruidException.Category.INVALID_INPUT)
.build(
t,
"Cannot coerce field [%s] class of [%s] to [%s]",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about including an action message here? @clintropolis - any suggestions?

@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch from ea6a82c to c99dd83 Compare June 30, 2023 01:25
@pranavbhole
Copy link
Copy Markdown
Contributor Author

@abhishekagarwal87 @clintropolis please review

@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch from c99dd83 to f0ad7b6 Compare June 30, 2023 02:39
@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch from f0ad7b6 to dc38717 Compare June 30, 2023 03:04
Comment thread sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java Outdated
@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch from 9d6e95f to 02ed241 Compare June 30, 2023 20:34
…java

fix the logging

Co-authored-by: Abhishek Agarwal <1477457+abhishekagarwal87@users.noreply.github.com>
@pranavbhole pranavbhole force-pushed the improvedLoggingIn_Coerce branch from 02ed241 to 4624644 Compare June 30, 2023 22:00
@abhishekagarwal87 abhishekagarwal87 merged commit 2d5b273 into apache:master Jul 3, 2023
@abhishekagarwal87 abhishekagarwal87 added this to the 27.0 milestone Jul 19, 2023
sergioferragut pushed a commit to sergioferragut/druid that referenced this pull request Jul 21, 2023
Logging the fieldName in the coerce exceptions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants