-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error object v2 #1371
Error object v2 #1371
Conversation
…ption-playing # Conflicts: # src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java
Co-authored-by: Aaron Morton <aaron.morton@datastax.com>
Co-authored-by: YuqiDu <istimdu@gmail.com> Co-authored-by: Tatu Saloranta <tatu.saloranta@datastax.com> Co-authored-by: Mahesh Rajamani <99678631+maheshrajamani@users.noreply.github.com> Co-authored-by: Jeffrey Carpenter <jeffrey.carpenter@datastax.com> Co-authored-by: Hazel <hazel.he@datastax.com> Co-authored-by: Kathiresan Selvaraj <96088452+kathirsvn@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Yuqi-Du <138714577+Yuqi-Du@users.noreply.github.com>
src/main/java/io/stargate/sgv2/jsonapi/api/model/command/impl/CreateCollectionCommand.java
Show resolved
Hide resolved
src/main/java/io/stargate/sgv2/jsonapi/exception/playing/APIException.java
Show resolved
Hide resolved
src/main/java/io/stargate/sgv2/jsonapi/exception/playing/APIException.java
Show resolved
Hide resolved
src/main/java/io/stargate/sgv2/jsonapi/exception/playing/APIException.java
Show resolved
Hide resolved
* and this exception is raised if the template and the code do not match. Note that it is OK for | ||
* the code to provide more variables than the template uses, but not the other way around. | ||
*/ | ||
public class UnresolvedErrorTemplateVariable extends RuntimeException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: we should probably have a root-level ultimate base exception for validity problems -- something like DataApiValidityException
(or whatever name is) extending RuntimeException
, being extended by this and other types (but not APIException
).
This is just a follow-up change idea, no need to change for this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
discussed, maybe later we can look at more base exceptions
*/ | ||
public class ServerException extends APIException { | ||
|
||
public static final ErrorFamily FAMILY = ErrorFamily.SERVER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is problematic:
- Should not really be
public
-- why would it be needed from outside (probablyprotected
for sub-classes) - Name is very vague, esp. when referred to from sub-classes. Maybe
SERVER_EXCEPTION_FAMILY
- ... or is this constant needed at all? Just use
ErrorFamily.SERVER
directly in sub-class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idea was for subclasses to all reference the same definition of the family during construction, e.g. in the ctor for the Code enum
|
||
public class DatabaseException extends ServerException { | ||
|
||
public static final Scope SCOPE = Scope.DATABASE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as with other constants:
- Should not be
public
? - Name is very generic/vague, probably
DEFAULT_SCOPE
. - ... but is this constant actually needed at all? Seems like its only used from sub-class.
Not 100% sure what to do with it, but just seems wrong. (1 and 2 easy enough to change, but eliminating need would be best)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idea was for the Code enum to be able to refence a central definition while it is constructing
private final ErrorTemplate<DatabaseException> template; | ||
|
||
Code() { | ||
template = ErrorTemplate.load(DatabaseException.class, FAMILY, SCOPE, name()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading from Enum instance constructors is extremely fragile -- I think it happens at class loading time -- and could cause really gnarly failure modes.
But then again, as long as our test coverage is good, maybe that's not a big issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohhhh. MAybe that is worse -- this is called once per each Enum value? Does it really try to load something, or is that misnamed method? (to me, loading means reading YAML config file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ErrorTemplate will cause the ErrorConfig to load, which happens once and loads all of the YAML config at once and only once.
Then this call to load() will fail if there is an error code defined in code but not in the yaml, so we want that failure to happen.
* <p>See {@link APIException} | ||
*/ | ||
@FunctionalInterface | ||
public interface ErrorScope { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this -- why not just a simple Enum? What is the point in this contraption?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
discussed - make it clear this is here because the scope is disjoint sets for the diff families
* | ||
* <p>Never {@code null}, uses "" for no scope. See {@link ErrorScope} | ||
*/ | ||
public final String scope; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to oddity of ErrorScope
, I am not sure why we use untyped String
, then functional interface for ErrorScope
? Why not plain old Enum value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the scope list is different for each family so there is no single enum with them all. i.e. we do not use the FILTER scope with a SERVER family.
super(errorInstance); | ||
} | ||
|
||
public enum Code implements ErrorCode<EmbeddingProviderException> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the idea it's ok to have same "code" (like CLIENT_ERROR) for multiple scopes? I guess that is the case.
One concern is that to know which problem you have, it is no longer possible to group failures solely by Code, as that will conflate Codes with different Scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add a fully qualified code to the API exception, we can then use it later for metrics etc
* | ||
* @return Instance of {@link APIException} the error code represents. | ||
*/ | ||
default T get() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a good method name. Get what?
So suggesting we rename to something like "toApiException()" or "asApiException()"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will look for better name - discussed
* "key-2", "value-2"] | ||
* @return Instance of {@link APIException} the error code represents. | ||
*/ | ||
default T get(String... values) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this method? We already have overload with Map
, why/where do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there to make it easy when there is only one or two variables to pass. The idea was to make it as easy as possible to instantiate exceptions
* Then use {@link #getErrorDetail(ErrorFamily, String, String)} if you want the template, or the | ||
* use {@link #getSnippetVars()} when running templates. | ||
* | ||
* <p>If you need more control use the {@link #initializeFromYamlResource(String)} before any code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... not necessarily easy/possible to do, due to class loading/initialization constraints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to be - revisit the comment with how this is used in testing
* | ||
* @return | ||
*/ | ||
public List<ErrorDetail> requestErrors() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have this?
* | ||
* @return | ||
*/ | ||
public List<ErrorDetail> serverErrors() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have this?
src/main/java/io/stargate/sgv2/jsonapi/exception/playing/ErrorConfig.java
Outdated
Show resolved
Hide resolved
Ok, so. I have a few concerns with the code included in here, at implementation details level. But at high level it makes sense; and so with the expectation of thorough testing (included in PR) I will approve this.
(earlier I had this too:
but I resolved it by removing/reducing access) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per my comment above, conditionally approving, just need to address concerns before or after merging.
What this PR does:
Initial error object v2
This is still not in use, it is dead code. Once we get it in we will move from the "playing" package into parent "exceptions" package once we start using it.
This PR is to get it into the main, next setps are:
Which issue(s) this PR fixes:
Fixes #
Checklist