AykutSarac/jsoncrack.com · warning

err

Error message

err

What it means

The catch fires when reading a dropped file via e[0].text() fails, or when setContents subsequently throws during format conversion. File-read failures are rare and usually indicate the file was locked/moved between drop and read, or the browser denied access. The toast tells the user the read failed.

Source

Thrown at apps/www/src/features/editor/FullscreenDropzone.tsx:25

import useFile from "../../store/useFile";

export const FullscreenDropzone = () => {
  const setContents = useFile(state => state.setContents);

  return (
    <Dropzone.FullScreen
      maxFiles={1}
      accept={["application/json", "application/x-yaml", "text/csv", "application/xml"]}
      onReject={files => toast.error(`Unable to load file ${files[0].file.name}`)}
      onDrop={async e => {
        try {
          const fileContent = await e[0].text();
          let fileExtension = e[0].name.split(".").pop() as FileFormat | undefined;
          if (!fileExtension) fileExtension = FileFormat.JSON;
          setContents({ contents: fileContent, format: fileExtension, hasChanges: false });
        } catch (err) {
          toast.error("An error occurred while reading the file.");
          console.error(err);
        }
      }}
    >
      <Group
        justify="center"
        ta="center"
        align="center"
        gap="xl"
        h="100vh"
        style={{ pointerEvents: "none" }}
      >
        <Dropzone.Accept>
          <VscFiles size={100} />
          <Text fz="h1" fw={500} mt="lg">
            Upload to JSON Crack
          </Text>
          <Text fz="lg" c="dimmed" mt="sm">
            (Max file size: 300 KB)

View on GitHub (pinned to 3c9af69e23)

Solutions

  1. Check e[0].size > 0 before reading.
  2. Enforce the 300KB size limit in onDrop as well as relying on onReject.
  3. Validate the inferred extension against the FileFormat enum before casting.
  4. Surface err.message in the toast for diagnosability.

Example fix

// before
const fileContent = await e[0].text();
let fileExtension = e[0].name.split(".").pop() as FileFormat | undefined;

// after
if (e[0].size === 0) {
  return toast.error("The selected file is empty.");
}
const fileContent = await e[0].text();
const ext = e[0].name.split(".").pop();
const fileExtension = isFileFormat(ext) ? ext : FileFormat.JSON;
Defensive patterns

Strategy: validation

Validate before calling

function isReadableFile(file: { size: number; name: string }): boolean {
  return file.size > 0 && file.size <= 300 * 1024;
}

Type guard

function isFileFormat(value: unknown): value is FileFormat {
  return typeof value === "string" && Object.values(FileFormat).includes(value as FileFormat);
}

Try / catch

onDrop={async e => {
  if (!isReadableFile(e[0])) {
    toast.error("File is empty or exceeds 300 KB.");
    return;
  }
  try {
    const fileContent = await e[0].text();
    const ext = e[0].name.split(".").pop();
    setContents({ contents: fileContent, format: isFileFormat(ext) ? ext : FileFormat.JSON, hasChanges: false });
  } catch (err) {
    toast.error("An error occurred while reading the file.");
    console.error(err);
  }
}}

Prevention

When it happens

Trigger: Dropping a file then the OS locks or removes it before text() resolves; dropping a directory/folder on a browser that exposes it as an unreadable entry; setContents throwing because content exceeds internal limits or fails format conversion.

Common situations: Dropping a 0-byte file; dropping from a network share that disconnects mid-read; large file where text() allocation fails; extension cast producing a FileFormat that contentToJson cannot parse.

Related errors


AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12). Data as JSON: /api/errors/fb1f5442895bc1c4. Report an issue: GitHub.