-
Notifications
You must be signed in to change notification settings - Fork 110
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
A comprehensive error handling strategy of pulling entities -- part II #528
base: master
Are you sure you want to change the base?
Conversation
Test Results 98 files - 9 98 suites - 9 4m 2s ⏱️ - 1m 30s Results for commit 184c8b1. ± Comparison against base commit 07e86c0. This pull request removes 50 tests.
♻️ This comment has been updated with latest results. |
5700899
to
a87cec7
Compare
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 are three big things here. First, these methods that return invalid entities cannot return type Entity. We will need a new type for this. Second, we also need APIs to get individual invalid entities by path. Third, the parameters used to filter on anything other than the entity path don't make sense when looking for invalid entities, since we may not be able to get any further information.
@@ -26,5 +26,7 @@ | |||
|
|||
List<Entity> getEntities(Predicate<String> entityPathPredicate, Predicate<String> classifierPathPredicate, Predicate<? super Map<String, ?>> entityContentPredicate); | |||
|
|||
List<Entity> getInvalidEntities(Predicate<String> entityPathPredicate, Predicate<String> classifierPathPredicate, Predicate<? super Map<String, ?>> entityContentPredicate); |
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 cannot return Entity, since what this will return is not a valid entity. There needs to be a new type for this (maybe call it InvalidEntity), which gives information on why this is not a valid entity and provides some kind of information that might help in fixing the entity. For the former, I would recommend an error message and/or stack trace. For the latter, I would recommend a string containing the actual source code.
It's also not clear whether classifierPathPredicate or entityContentPredicate really make sense here. Since we can't assume that the entity can be deserialized, we can't be sure we'll be able to test those predicates.
Finally, there should be an API to get a single invalid entity by its path.
@@ -923,5 +939,18 @@ synchronized Entity getEntity() | |||
} | |||
return this.entity; | |||
} | |||
|
|||
synchronized Entity getInvalidEntity() |
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 with EntityAccessContext, this cannot return Entity. If the entity is indeed invalid, you should cache that fact and check it both in this method and in getEntity.
Also, this needs to check for any kind of invalidity, not just a path mismatch. If an entity cannot be deserialized for any reason, it is invalid.
...er/src/main/java/org/finos/legend/sdlc/server/resources/BackupWorkspaceEntitiesResource.java
Outdated
Show resolved
Hide resolved
5354817
to
39068b4
Compare
@@ -31,5 +32,9 @@ default List<Entity> getEntities(Predicate<String> entityPathPredicate, Predicat | |||
|
|||
List<Entity> getEntities(Predicate<String> entityPathPredicate, Predicate<String> classifierPathPredicate, Predicate<? super Map<String, ?>> entityContentPredicate, boolean excludeInvalid); | |||
|
|||
InvalidEntity getInvalidEntity(String path); | |||
|
|||
List<InvalidEntity> getInvalidEntities(); |
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.
Let's add a path predicate to getInvalidEntities so that they can be filtered. Also, let's add a method to get just the paths of invalid entities.
List<InvalidEntity> getInvalidEntities(); | |
List<InvalidEntity> getInvalidEntities(Predicate<String> entityPathPredicate); | |
List<String> getInvalidEntityPaths(Predicate<String> entityPathPredicate); |
|
||
String getErrorMessage(); | ||
|
||
String getStackTrace(); |
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.
Let's call this getErrorDetail instead of getStackTrace. That makes it a bit more generic, in case we have something other than a stack trace that we'd want to include.
String getStackTrace(); | |
String getErrorDetail(); |
{ | ||
return InvalidEntity.newInvalidEntity(path, e.getMessage(), e.getStackTrace().toString(), file.getContentAsString()); | ||
} | ||
} |
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.
If we find the entity and it is valid, then we should throw an exception that says that the entity is valid. I'm not sure what the status code should be for this case. 404 doesn't seem quite right, since we did actually find the entity. But I can't think of something better. Maybe 409?
} | ||
} | ||
} | ||
throw new LegendSDLCServerException("Unknown invalid entity " + path + " for " + getInfoForException(), Status.NOT_FOUND); |
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 exception should only occur if we don't find any file at all for the entity.
throw new LegendSDLCServerException("Unknown invalid entity " + path + " for " + getInfoForException(), Status.NOT_FOUND); | |
throw new LegendSDLCServerException("Unknown entity " + path + " for " + getInfoForException(), Status.NOT_FOUND); |
if (this.entity == null) | ||
{ | ||
try | ||
{ | ||
Entity localEntity = this.sourceDirectory.deserialize(this.file); | ||
if (!Objects.equals(localEntity.getPath(), getEntityPath())) | ||
{ | ||
throw new RuntimeException("Expected entity path " + getEntityPath() + ", found " + localEntity.getPath()); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
return InvalidEntity.newInvalidEntity(getEntityPath(), e.getMessage(), e.getStackTrace().toString(), this.file.getContentAsString()); | ||
} | ||
} |
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.
if (this.entity == null) | |
{ | |
try | |
{ | |
Entity localEntity = this.sourceDirectory.deserialize(this.file); | |
if (!Objects.equals(localEntity.getPath(), getEntityPath())) | |
{ | |
throw new RuntimeException("Expected entity path " + getEntityPath() + ", found " + localEntity.getPath()); | |
} | |
} | |
catch (Exception e) | |
{ | |
return InvalidEntity.newInvalidEntity(getEntityPath(), e.getMessage(), e.getStackTrace().toString(), this.file.getContentAsString()); | |
} | |
} | |
try | |
{ | |
getEntity(); | |
} | |
catch (Exception e) | |
{ | |
return InvalidEntity.newInvalidEntity(getEntityPath(), e.getMessage(), e.getStackTrace().toString(), this.file.getContentAsString()); | |
} |
39068b4
to
184c8b1
Compare
Add new endpoints for pulling invalid entities.
If there is no invalid entity, the return value will be [].
Screen.Recording.2022-10-05.at.11.31.03.AM.mov