Skip to content

Commit

Permalink
Catch exceptions when creating traits
Browse files Browse the repository at this point in the history
Some traits like the http trait will throw exceptions that are not
SourceExceptions. This previously would cause the CLI to stop on
the first exception and not show pretty error output. This fixes that
by catching RuntimeExceptions to turn them into ValidationEvents.
  • Loading branch information
mtdowling committed Aug 24, 2023
1 parent da5924f commit 0f1c378
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package software.amazon.smithy.model.loader;

import static java.lang.String.format;
import static software.amazon.smithy.model.validation.Severity.ERROR;
import static software.amazon.smithy.model.validation.Validator.MODEL_ERROR;

import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -107,6 +109,17 @@ private Trait createTrait(ShapeId target, ShapeId traitId, Node traitValue) {
String message = format("Error creating trait `%s`: ", Trait.getIdiomaticTraitName(traitId));
events.add(ValidationEvent.fromSourceException(e, message, target));
return null;
} catch (RuntimeException e) {
events.add(ValidationEvent.builder()
.id(MODEL_ERROR)
.severity(ERROR)
.shapeId(target)
.sourceLocation(traitValue)
.message(format("Error creating trait `%s`: %s",
Trait.getIdiomaticTraitName(traitId),
e.getMessage()))
.build());
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1317,4 +1317,28 @@ public void modelLoadingErrorsAreEmittedToListener() {
assertThat(result.getValidationEvents(Severity.ERROR), hasSize(1));
assertThat(events, equalTo(result.getValidationEvents()));
}

@Test
public void exceptionsThrownWhenCreatingTraitsDontCrashSmithy() {
String document = "{\n"
+ "\"smithy\": \"" + Model.MODEL_VERSION + "\",\n"
+ " \"shapes\": {\n"
+ " \"ns.foo#Test\": {\n"
+ " \"type\": \"string\",\n"
+ " \"traits\": {\"smithy.foo#baz\": true}\n"
+ " }\n"
+ " }\n"
+ "}";
ValidatedResult<Model> result = new ModelAssembler()
.addUnparsedModel(SourceLocation.NONE.getFilename(), document)
.putProperty(ModelAssembler.ALLOW_UNKNOWN_TRAITS, true)
.traitFactory((traitId, target, value) -> {
throw new RuntimeException("Oops!");
})
.assemble();

assertThat(result.getValidationEvents(Severity.ERROR), not(empty()));
assertThat(result.getValidationEvents(Severity.ERROR).get(0).getMessage(),
equalTo("Error creating trait `smithy.foo#baz`: Oops!"));
}
}

0 comments on commit 0f1c378

Please sign in to comment.