Skip to content

Using DruidExceptions in MSQ (changes related to the Broker)#14534

Merged
LakshSingla merged 16 commits intoapache:masterfrom
LakshSingla:error-code-msq
Jul 13, 2023
Merged

Using DruidExceptions in MSQ (changes related to the Broker)#14534
LakshSingla merged 16 commits intoapache:masterfrom
LakshSingla:error-code-msq

Conversation

@LakshSingla
Copy link
Copy Markdown
Contributor

Description

Most of the places in MSQ currently rely on the older error code, dating pre #14004. This is an attempt to fix the bits of the error code in the places where bits of MSQ reside in the broker. This extends upon the PR #14531.

  1. The MSQTaskQueryMaker and the MSQTaskEngine might return a different error code for some invalid cases (which might not be inline with what the behavior originally was, but is correct now). For example, setting maxNumTasks to 1 would return a 500 error code, which is not right since its an invalid user input. This was the original behavior, and this PR changes that.
  2. The EXTERN function returns a 400 error code if the parameters to it are incorrect (which is in line with what its behavior originally was and is correct)

Note: This PR doesn't unify the DruidExceptions with the MSQException

Release note

MSQ engine returns correct error codes for invalid user inputs in the query context


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

@somu-imply somu-imply left a comment

Choose a reason for hiding this comment

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

Looks good. Minor nits

Comment on lines +143 to +147
.build(
e,
"Unable to deserialize the insert granularity. Please retry the query with a "
+ "valid segment graularity"
);
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.

This message reads to me like it's trying to get to the end user, but a defensive exception is something that we expect to never happen (because the code doesn't allow it) and therefore it faces the developer. Given this message, are you sure that this isn't an InvalidSqlInput?

Copy link
Copy Markdown
Contributor Author

@LakshSingla LakshSingla Jul 10, 2023

Choose a reason for hiding this comment

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

This would only be thrown if we can't serialize one of the objects predefined in the code which we are sure would get serialized. (Handles the jsonMapper.writeValueAsString throw clause). We never intend to encounter this exception, and if we do, there's something wrong with the code. Updated the error message to indicate this.

Comment on lines +153 to +156
throw InvalidInput.exception(
"%s cannot be less than 2 since at least 1 controller and 1 worker is necessary.",
MultiStageQueryContext.CTX_MAX_NUM_TASKS
);
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.

This message doesn't follow our conventions for how to write error messages or interpolate things. Please read style-conventions.md and adjust.

In this case, I would probably suggest

"MSQ context maxNumTasks [%,d] cannot be less than 2, since at least 1 controller and 1 worker is necessary"

Comment on lines +213 to +215
throw DruidException.forPersona(DruidException.Persona.DEVELOPER)
.ofCategory(DruidException.Category.DEFENSIVE)
.build("Cannot INSERT with destination [%s]", ctxDestination);
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.

This message again doesn't seem defensive, it seems like it's intended for the end-user and should be InvalidSqlInput no?

Comment on lines +223 to +225
throw DruidException.forPersona(DruidException.Persona.DEVELOPER)
.ofCategory(DruidException.Category.DEFENSIVE)
.build("Unable to convert %s to a segment granularity", segmentGranularity);
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.

This is throwing away the Exception e so we will never be able to figure out why we were unable to convert the value. It also doesn't follow our conventions for how to write and interpolate messages and I'm not sure that it's truly defensive?

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.

Good point on keeping the exception. I updated the exception message to state why this is a defensive exception.

This parameter is added by Druid while processing PARTITIONED BY _____. User inputs whatever is in front of the partitioned by we populate the query context based on that. Therefore whatever hits this exception has been sanitized and populated by us (after already going through a transformation-serialization process). We don't ever wish to encounter this in a normal misinput situation, any exception or incorrect input from the user would have been flagged by the SQL parser or while serializing.

)
)
InvalidInput.exception(
"The statement sql api only supports sync mode[%s]. Please set context parameter [%s=%s] in the context payload",
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'm not sure I know what the statement sql api is? If it's only supposed to be one thing and this code knows what that one thing is and the user got their request to this line of the code, why does the user need to change their query to only do the one thing that this code can do? I.e. why not just ignore the context parameter entirely? Or overwrite it with the one value that this code can do?

Copy link
Copy Markdown
Contributor

@cryptoe cryptoe Jul 10, 2023

Choose a reason for hiding this comment

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

Since the sql statement api will support the sync mode soon, I wanted the user to set the flag explicitly.

Rolling upgrades then become easy since we donot have a default mode/overridden mode.

The mode also changes the way the results are fetched.
If the mode set is async, the results are fetched via the results api.
If the mode set is sync, then the results are streamed back in the same post request. (At-least, that's how I envision it. )

Copy link
Copy Markdown
Contributor Author

@LakshSingla LakshSingla Jul 11, 2023

Choose a reason for hiding this comment

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

I went through the code, and ExecutionMode is currently unused. I have left it as is since I am not aware if it will be utilized later, however, I changed the exception to defensive since this parameter isn't supported, unset, and not documented, therefore it shouldn't have been set.

(cc @cryptoe, I can clean this up in case we can remove the class)

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.

Its used in SqlStatementResource#contextChecks

Comment thread processing/src/main/java/org/apache/druid/error/InvalidInput.java Outdated
@cryptoe cryptoe added this to the 27.0 milestone Jul 10, 2023
@cryptoe cryptoe added the Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 label Jul 10, 2023
@LakshSingla
Copy link
Copy Markdown
Contributor Author

LakshSingla commented Jul 11, 2023

@imply-cheddar Thanks a lot for the review, I have revised the PR with the changes, and better exception messages.

Copy link
Copy Markdown
Contributor

@cryptoe cryptoe left a comment

Choose a reason for hiding this comment

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

Left some nit's.
LGTM otherwise.

Copy link
Copy Markdown
Contributor

@cryptoe cryptoe left a comment

Choose a reason for hiding this comment

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

Changes LGTM.

@LakshSingla LakshSingla merged commit c1c7dff into apache:master Jul 13, 2023
LakshSingla added a commit to LakshSingla/druid that referenced this pull request Jul 14, 2023
…14534)

MSQ engine returns correct error codes for invalid user inputs in the query context. Also, using DruidExceptions for MSQ related errors happening in the Broker with improved error messages.
cryptoe pushed a commit that referenced this pull request Jul 17, 2023
…#14586)

MSQ engine returns correct error codes for invalid user inputs in the query context. Also, using DruidExceptions for MSQ related errors happening in the Broker with improved error messages.
sergioferragut pushed a commit to sergioferragut/druid that referenced this pull request Jul 21, 2023
…14534)

MSQ engine returns correct error codes for invalid user inputs in the query context. Also, using DruidExceptions for MSQ related errors happening in the Broker with improved error messages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants