Skip to content
33 changes: 17 additions & 16 deletions apps/roam/src/components/CreateRelationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { render as renderToast } from "roamjs-components/components/Toast";
import MenuItemSelect from "roamjs-components/components/MenuItemSelect";
import AutocompleteInput from "roamjs-components/components/AutocompleteInput";
import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid";
import sendErrorEmail from "~/utils/sendErrorEmail";
import { getSetting } from "~/utils/extensionSettings";
import getDiscourseRelations, {
type DiscourseRelation,
Expand All @@ -22,6 +21,7 @@ import { findDiscourseNodeByTitleAndUid } from "~/utils/findDiscourseNode";
import { getDiscourseNodeFormatInnerExpression } from "~/utils/getDiscourseNodeFormatExpression";
import type { DiscourseNode } from "~/utils/getDiscourseNodes";
import type { Result } from "~/utils/types";
import internalError from "~/utils/internalError";
import getDiscourseNodes from "~/utils/getDiscourseNodes";

export type CreateRelationDialogProps = {
Expand All @@ -39,15 +39,6 @@ type ExtendedCreateRelationDialogProps = CreateRelationDialogProps & {
selectedSourceType: DiscourseNode;
};

const internalError = (msg: string) => {
process.env.NODE_ENV === "development"
? console.error(msg)
: void sendErrorEmail({
error: new Error(msg),
type: "Create Relation Dialog Failed",
}).catch(() => {});
};

const CreateRelationDialog = ({
onClose,
sourceNodeUid,
Expand Down Expand Up @@ -112,7 +103,10 @@ const CreateRelationDialog = ({
});
if (selectedTargetType === false) {
// should not happen at this point, since the pattern was vetted at input.
internalError("Could not find identify node downstream");
internalError({
type: "Create Relation dialog",
error: "Could not identify node downstream",
});
return null;
}
const candidateRelations = relDataByTag[selectedRelationName].filter(
Expand All @@ -132,14 +126,18 @@ const CreateRelationDialog = ({
);
if (candidateRelations.length === 0) {
// also should not happen
internalError("Could not find the relation");
internalError({
type: "Create Relation dialog",
error: "Could not find the relation",
});
return null;
}
if (candidateRelations.length !== 1) {
// This seems to happen... I need more data.
internalError(
`Too many relations between ${selectedTargetType.type} and ${selectedSourceType.type}: ${candidateRelations.map((r) => r.id).join(",")}`,
);
internalError({
type: "Create Relation dialog",
error: `Too many relations between ${selectedTargetType.type} and ${selectedSourceType.type}: ${candidateRelations.map((r) => r.id).join(",")}`,
});
return null;
}
return candidateRelations[0];
Expand Down Expand Up @@ -288,7 +286,10 @@ const prepareRelData = (
});
if (!nodeSchema) {
// should not happen at this point, since the pattern was vetted at input.
internalError("Could not find identify node downstream");
internalError({
error: "Could not identify node downstream",
type: "Create Relation dialog",
});
return [];
}
// note the same relation could be used in both directions
Expand Down
37 changes: 20 additions & 17 deletions apps/roam/src/components/Export.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import {
import calcCanvasNodeSizeAndImg from "~/utils/calcCanvasNodeSizeAndImg";
import { DiscourseNodeShape } from "~/components/canvas/DiscourseNodeUtil";
import { MAX_WIDTH } from "~/components/canvas/Tldraw";
import sendErrorEmail from "~/utils/sendErrorEmail";
import internalError from "~/utils/internalError";
import { getSetting, setSetting } from "~/utils/extensionSettings";

const ExportProgress = ({ id }: { id: string }) => {
Expand Down Expand Up @@ -468,13 +468,12 @@ const ExportDialog: ExportDialogComponent = ({
id: "query-builder-export-success",
});
} catch (e) {
const error = e as Error;
renderToast({
content: "Looks like there was an error. The team has been notified.",
intent: "danger",
id: "discourse-graphs-error",
internalError({
error: e as Error,
type: "Export Dialog Failed",
userMessage:
"Looks like there was an error. The team has been notified.",
});
sendErrorEmail({ error, type: "Export Dialog Failed" }).catch(() => {});
} finally {
setLoading(false);
onClose();
Expand Down Expand Up @@ -688,18 +687,22 @@ const ExportDialog: ExportDialogComponent = ({
setError(`Unsupported export type: ${exportType}`);
}
} catch (e) {
const error = e as Error;
renderToast({
id: "export-error",
content:
internalError({
error: e as Error,
type: "Export Dialog Failed",
userMessage:
"Looks like there was an error. The team has been notified.",
intent: "danger",
context: {
activeExportType,
filename,
resultsCount: Array.isArray(results)
? results.length
: undefined,
sampleUids: Array.isArray(results)
? results.slice(0, 10).map((r) => r.uid)
: undefined,
},
});
sendErrorEmail({
error,
type: "Export Dialog Failed",
context: { activeExportType, filename, results },
}).catch(() => {});
setDialogOpen(true);
setError((e as Error).message);
} finally {
Expand Down
61 changes: 21 additions & 40 deletions apps/roam/src/components/canvas/Clipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import { MAX_WIDTH } from "./Tldraw";
import getBlockProps from "~/utils/getBlockProps";
import setBlockProps from "~/utils/setBlockProps";
import { measureCanvasNodeText } from "~/utils/measureCanvasNodeText";
import sendErrorEmail from "~/utils/sendErrorEmail";
import internalError from "~/utils/internalError";

export type ClipboardPage = {
uid: string;
Expand All @@ -79,21 +79,6 @@ const ClipboardContext = createContext<ClipboardContextValue | null>(null);

const CLIPBOARD_PROP_KEY = "pages";

const toError = (error: unknown, fallbackMessage: string): Error => {
if (error instanceof Error) {
return error;
}
if (typeof error === "string") {
return new Error(error);
}
try {
const serialized = JSON.stringify(error);
return new Error(serialized || fallbackMessage);
} catch {
return new Error(fallbackMessage);
}
};

const getOrCreateClipboardBlock = async (
canvasPageTitle: string,
userUid: string,
Expand Down Expand Up @@ -155,11 +140,13 @@ export const ClipboardProvider = ({
try {
const userUid = getCurrentUserUid();
if (!userUid) {
sendErrorEmail({
internalError({
error: new Error("Missing current user UID"),
type: "Canvas Clipboard: Missing current user UID",
context: { canvasPageTitle },
}).catch(() => {});
context: {
canvasPageTitle,
},
});
setIsInitialized(true);
return;
}
Expand All @@ -179,13 +166,12 @@ export const ClipboardProvider = ({
) {
setPages(storedPages as ClipboardPage[]);
}
} catch (e) {
const normalizedError = toError(e, "Failed to initialize clipboard");
sendErrorEmail({
error: normalizedError,
} catch (error) {
internalError({
error,
type: "Canvas Clipboard: Failed to initialize",
context: { canvasPageTitle },
}).catch(() => {});
});
} finally {
setIsInitialized(true);
}
Expand All @@ -201,13 +187,12 @@ export const ClipboardProvider = ({
setBlockProps(clipboardBlockUid, {
[CLIPBOARD_PROP_KEY]: pages,
});
} catch (e) {
const normalizedError = toError(e, "Failed to persist clipboard state");
sendErrorEmail({
error: normalizedError,
} catch (error) {
internalError({
error,
type: "Canvas Clipboard: Failed to persist state",
context: { clipboardBlockUid, pageCount: pages.length },
}).catch(() => {});
});
}
}, [pages, clipboardBlockUid, isInitialized]);

Expand Down Expand Up @@ -287,8 +272,8 @@ const AddPageModal = ({ isOpen, onClose, onConfirm }: AddPageModalProps) => {
// eslint-disable-next-line @typescript-eslint/await-thenable
const raw = await window.roamAlphaAPI.data.backend.q(
`
[:find ?text ?uid
:where
[:find ?text ?uid
:where
[?e :node/title ?text]
[?e :block/uid ?uid]]`,
);
Expand Down Expand Up @@ -447,15 +432,11 @@ const ClipboardPageSection = ({
);
setDiscourseNodes(nodes);
} catch (error) {
const normalizedError = toError(
internalError({
error,
"Failed to fetch discourse nodes",
);
sendErrorEmail({
error: normalizedError,
type: "Canvas Clipboard: Failed to fetch discourse nodes",
context: { pageTitle: page.text },
}).catch(() => {});
});
setDiscourseNodes([]);
} finally {
setIsLoading(false);
Expand Down Expand Up @@ -610,11 +591,11 @@ const ClipboardPageSection = ({

const nodeType = findDiscourseNode(node.uid);
if (!nodeType) {
sendErrorEmail({
error: new Error("Node type not found"),
internalError({
error: new Error("Canvas Clipboard: Node type not found"),
type: "Canvas Clipboard: Node type not found",
context: { uid: node.uid },
}).catch(() => {});
});
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import getCurrentPageUid from "roamjs-components/dom/getCurrentPageUid";
import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid";
import { AddReferencedNodeType } from "./DiscourseRelationTool";
import { dispatchToastEvent } from "~/components/canvas/ToastListener";
import sendErrorEmail from "~/utils/sendErrorEmail";
import internalError from "~/utils/internalError";

const COLOR_ARRAY = Array.from(textShapeProps.color.values)
.filter((c) => !["red", "green", "grey"].includes(c))
Expand Down Expand Up @@ -564,12 +564,10 @@ export const createAllRelationShapeUtils = (
relationBlockUid: relation.id,
});
else {
void sendErrorEmail({
error: new Error(
"attempt to create a relation between non discourse nodes",
),
type: "canvas-create-relation-non-dgn",
}).catch(() => undefined);
void internalError({
error: "attempt to create a relation between non discourse nodes",
type: "Canvas create relation",
});
}
} else {
const { triples, label: relationLabel } = relation;
Expand Down
8 changes: 3 additions & 5 deletions apps/roam/src/components/canvas/Tldraw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import { createMigrations } from "./DiscourseRelationShape/discourseRelationMigr
import ToastListener, { dispatchToastEvent } from "./ToastListener";
import { CanvasDrawerPanel } from "./CanvasDrawer";
import { ClipboardPanel, ClipboardProvider } from "./Clipboard";
import sendErrorEmail from "~/utils/sendErrorEmail";
import internalError from "~/utils/internalError";
import { AUTO_CANVAS_RELATIONS_KEY } from "~/data/userSettings";
import { getSetting } from "~/utils/extensionSettings";
import { isPluginTimerReady, waitForPluginTimer } from "~/utils/pluginTimer";
Expand Down Expand Up @@ -516,16 +516,14 @@ const TldrawCanvas = ({ title }: { title: string }) => {
error.stack = e.detail.stack;
}

sendErrorEmail({
internalError({
error,
type: "Tldraw Error",
context: {
title: title,
lastActions: lastActionsRef.current,
},
}).catch(() => {});

console.error("Tldraw Error:", e.detail);
});
};

document.addEventListener(
Expand Down
23 changes: 10 additions & 13 deletions apps/roam/src/components/canvas/useRoamStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import {
} from "tldraw";
import { AddPullWatch } from "roamjs-components/types";
import { LEGACY_SCHEMA } from "~/data/legacyTldrawSchema";
import sendErrorEmail from "~/utils/sendErrorEmail";
import getCurrentUserDisplayName from "roamjs-components/queries/getCurrentUserDisplayName";
import internalError from "~/utils/internalError";

const THROTTLE = 350;

Expand Down Expand Up @@ -137,26 +136,25 @@ export const useRoamStore = ({

const handleStoreError = ({
error,
errorMessage,
type,
}: {
error: Error;
errorMessage: string;
type: string;
}): void => {
console.error(errorMessage, error);
setError(error);
setLoading(false);
const snapshotSize = initialSnapshot
? JSON.stringify(initialSnapshot).length
: 0;
sendErrorEmail({
internalError({
error,
type: errorMessage,
type,
context: {
pageUid,
snapshotSize,
...(snapshotSize < 10000 ? { initialSnapshot } : {}),
},
}).catch(() => {});
});
};

// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -171,7 +169,7 @@ export const useRoamStore = ({
} catch (e) {
handleStoreError({
error: e as Error,
errorMessage: "Failed to create TLStore",
type: "Failed to create TLStore",
});
return null;
}
Expand All @@ -182,7 +180,7 @@ export const useRoamStore = ({
} catch (e) {
handleStoreError({
error: e as Error,
errorMessage: "Failed to migrate snapshot",
type: "Failed to migrate snapshot",
});
return null;
}
Expand Down Expand Up @@ -305,14 +303,13 @@ export const useRoamStore = ({
setNeedsUpgrade(false);
setInitialSnapshot(null);
setError(error);
sendErrorEmail({
internalError({
error,
type: "Failed to perform Canvas upgrade",
context: {
data: { oldData },
},
}).catch(() => {});
console.error("Failed to perform Canvas upgrade", error);
});
}
};

Expand Down
Loading