Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ describe("executeUserQuery", () => {
executeUserQuery("query", mockUpdateSchema)
);

await expect(result).rejects.toThrow("Failed to fetch entity details");
await expect(result).rejects.toThrow(
"Failed to fetch the details of 2 vertices and 1 edge."
);
expect(rawQuerySpy).toBeCalledTimes(1);
expect(vertexDetailsSpy).toBeCalledTimes(1);
expect(edgeDetailsSpy).toBeCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import {
createTestableVertex,
FakeExplorer,
} from "@/utils/testing";
import { patchEntityDetails } from "./patchEntityDetails";
import {
patchEntityDetails,
PatchEntityDetailsError,
} from "./patchEntityDetails";
import { createQueryClient } from "@/core/queryClient";
import {
createResultScalar,
Expand Down Expand Up @@ -222,4 +225,77 @@ describe("patchEntityDetails", () => {

expect(result).toStrictEqual([expectedBundle]);
});

it("should throw when source vertex not found", async () => {
const explorer = new FakeExplorer();
const client = createQueryClient({ explorer });

const edge = createTestableEdge();
explorer.addTestableEdge(edge);
explorer.vertexMap.delete(edge.source.id);

await expect(() =>
patchEntityDetails(client, [edge.asFragmentResult()])
).rejects.toThrow(
new PatchEntityDetailsError("Failed to fetch the details of 1 vertex.")
);
});

it("should throw when target vertex not found", async () => {
const explorer = new FakeExplorer();
const client = createQueryClient({ explorer });

const edge = createTestableEdge();
explorer.addTestableEdge(edge);
explorer.vertexMap.delete(edge.target.id);

await expect(() =>
patchEntityDetails(client, [edge.asFragmentResult()])
).rejects.toThrow(
new PatchEntityDetailsError("Failed to fetch the details of 1 vertex.")
);
});

it("should throw when edge full details not found", async () => {
const explorer = new FakeExplorer();
const client = createQueryClient({ explorer });

const edge = createTestableEdge();
explorer.addTestableEdge(edge);
explorer.edgeMap.delete(edge.id);

await expect(() =>
patchEntityDetails(client, [edge.asFragmentResult()])
).rejects.toThrow(
new PatchEntityDetailsError("Failed to fetch the details of 1 edge.")
);
});

it("should throw when multiple vertices and edges are not found", async () => {
const explorer = new FakeExplorer();
const client = createQueryClient({ explorer });

const vertex = createTestableVertex();
const edge1 = createTestableEdge();
const edge2 = createTestableEdge();
explorer.addTestableVertex(vertex);
explorer.addTestableEdge(edge1);
explorer.addTestableEdge(edge2);
explorer.vertexMap.delete(vertex.id);
explorer.vertexMap.delete(edge1.source.id);
explorer.edgeMap.delete(edge1.id);
explorer.edgeMap.delete(edge2.id);

await expect(() =>
patchEntityDetails(client, [
vertex.asFragmentResult(),
edge1.asFragmentResult(),
edge2.asFragmentResult(),
])
).rejects.toThrow(
new PatchEntityDetailsError(
"Failed to fetch the details of 2 vertices and 2 edges."
)
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,30 @@ export async function patchEntityDetails(

// Ensure all details are fetched
if (missingVertices.length > 0 || missingEdges.length > 0) {
const vertexCount =
missingVertices.length === 0
? null
: missingVertices.length === 1
? "1 vertex"
: `${missingVertices.length} vertices`;
const edgeCount =
missingEdges.length === 0
? null
: missingEdges.length === 1
? "1 edge"
: `${missingEdges.length} edges`;

const missingCount =
vertexCount && edgeCount
? `${vertexCount} and ${edgeCount}`
: vertexCount || edgeCount || "";
logger.error("Failed to fetch fragment entity details", {
missingVertices,
missingEdges,
});
throw new Error("Failed to fetch entity details");
throw new PatchEntityDetailsError(
`Failed to fetch the details of ${missingCount}.`
);
}

// Create a mapping from vertex ID to full vertex details
Expand Down Expand Up @@ -76,7 +95,7 @@ function patchVertex(
const fullVertex = vertexDetailsMap.get(vertex.id);

if (!fullVertex) {
throw new Error("Failed to fetch vertex details");
throw new PatchEntityDetailsError("Failed to fetch vertex details");
}

return createPatchedResultVertex({
Expand All @@ -94,8 +113,21 @@ function patchEdge(
const fullSource = vertexDetailsMap.get(edge.sourceId);
const fullTarget = vertexDetailsMap.get(edge.targetId);

if (!fullEdge || !fullSource || !fullTarget) {
throw new Error("Failed to fetch edge details");
if (!fullEdge) {
throw new PatchEntityDetailsError(
"Could not find the full details of the edge"
);
}

if (!fullSource) {
throw new PatchEntityDetailsError(
"Could not find the full details of the source vertex"
);
}
if (!fullTarget) {
throw new PatchEntityDetailsError(
"Could not find the full details of the target vertex"
);
}

return createPatchedResultEdge({
Expand All @@ -118,3 +150,11 @@ function patchBundle(
),
};
}

export class PatchEntityDetailsError extends Error {
constructor(message: string) {
super(message);
this.name = "PatchEntityDetailsError";
Object.setPrototypeOf(this, PatchEntityDetailsError.prototype);
}
}
8 changes: 8 additions & 0 deletions packages/graph-explorer/src/utils/createDisplayError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ZodError } from "zod";
import { NetworkError } from "./NetworkError";
import { isCancellationError } from "./isCancellationError";
import { PatchEntityDetailsError } from "@/connector/queries/patchEntityDetails";

export type DisplayError = {
title: string;
Expand Down Expand Up @@ -118,6 +119,13 @@ export function createDisplayError(error: any): DisplayError {
};
}

if (error instanceof PatchEntityDetailsError) {
return {
title: "Failed to update entity details",
message: error.message,
};
}

if (error instanceof ZodError) {
return {
title: "Unrecognized Result Format",
Expand Down