Skip to content

Commit

Permalink
Collect all extraction errors before reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Nov 3, 2023
1 parent 61eb1e4 commit 1ccab75
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
18 changes: 15 additions & 3 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Extractor } from "./Extractor";
import { GratsDefinitionNode, TypeContext } from "./TypeContext";
import { validateSDL } from "graphql/validation/validate";
import { applyServerDirectives, DIRECTIVES_AST } from "./serverDirectives";
import { extend } from "./utils/helpers";

export { applyServerDirectives } from "./serverDirectives";

Expand Down Expand Up @@ -94,6 +95,8 @@ function extractSchema(
const definitions: GratsDefinitionNode[] = Array.from(
DIRECTIVES_AST.definitions,
);

const errors: ts.Diagnostic[] = [];
for (const sourceFile of program.getSourceFiles()) {
// If the file doesn't contain any GraphQL definitions, skip it.
if (!/@gql/i.test(sourceFile.text)) {
Expand All @@ -104,7 +107,8 @@ function extractSchema(
// If the user asked for us to report TypeScript errors, then we'll report them.
const typeErrors = ts.getPreEmitDiagnostics(program, sourceFile);
if (typeErrors.length > 0) {
return err(typeErrors as ts.Diagnostic[]);
extend(errors, typeErrors);
continue;
}
} else {
// Otherwise, we will only report syntax errors, since they will prevent us from
Expand All @@ -113,18 +117,26 @@ function extractSchema(
if (syntaxErrors.length > 0) {
// It's not very helpful to report multiple syntax errors, so just report
// the first one.
return err([syntaxErrors[0]]);
errors.push(syntaxErrors[0]);
continue;
}
}

const extractor = new Extractor(sourceFile, ctx, gratsOptions);
const extractedResult = extractor.extract();
if (extractedResult.kind === "ERROR") return extractedResult;
if (extractedResult.kind === "ERROR") {
extend(errors, extractedResult.err);
continue;
}
for (const definition of extractedResult.value) {
definitions.push(definition);
}
}

if (errors.length > 0) {
return err(errors);
}

// If you define a field on an interface using the functional style, we need to add
// that field to each concrete type as well. This must be done after all types are created,
// but before we validate the schema.
Expand Down
2 changes: 1 addition & 1 deletion src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class DefaultMap<K, V> {
}

// Similar to a.push(...b), but avoids potential stack overflows.
export function extend<T>(a: T[], b: T[]) {
export function extend<T>(a: T[], b: readonly T[]) {
for (const item of b) {
a.push(item);
}
Expand Down

0 comments on commit 1ccab75

Please sign in to comment.