-
-
Notifications
You must be signed in to change notification settings - Fork 763
Open
Description
Provide environment information
System:
OS: Linux 6.6 Ubuntu 20.04.6 LTS (Focal Fossa)
CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
Memory: 10.45 GB / 15.58 GB
Container: Yes
Shell: 3.7.1 - /usr/bin/fish
Binaries:
Node: 18.20.8 - ~/.local/share/nvm/v18.20.8/bin/node
npm: 10.8.2 - ~/.local/share/nvm/v18.20.8/bin/npm
pnpm: 8.6.3 - ~/.local/share/pnpm/pnpm
Describe the bug
Uncaught Error: Class extends value [object Object] is not a constructor or null
Reproduction repo
not at this point
To reproduce
important to know that this happens simply by importing the package, it's not triggered.
This is in the parent component ('use client'
). runId
and publicAccesstoken
are null
.
{runId && publicAccessToken ? (
<DecryptionLoadingDialog
runId={runId}
publicAccessToken={publicAccessToken}
callback={props.callback}
/>
) : null}
Does not work:
import { useRealtimeRun } from '@trigger.dev/react-hooks';
import { LoaderCircle } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { twMerge } from 'tailwind-merge';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import type { decryptLink } from '@/trigger/decrypt-link';
import type { OpenLinkOptions } from '../types/OpenLinkOptions';
type Props = {
runId: string;
publicAccessToken: string;
callback: (options: OpenLinkOptions) => void;
};
export const DecryptionLoadingDialog = ({
runId,
publicAccessToken,
callback,
}: Props) => {
const router = useRouter();
const [open, setOpen] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [attempt, setAttempt] = useState(1);
const { run, error } = useRealtimeRun<typeof decryptLink>(runId, {
accessToken: publicAccessToken,
});
useEffect(() => {
if (!run) return;
console.log('🚀 ~ run:', run);
if (run.status === 'QUEUED') {
setIsLoading(true);
}
if (run.status === 'REATTEMPTING') {
setAttempt((prev) => prev + 1);
}
if (run.status === 'FAILED' || run.status === 'COMPLETED') {
setIsLoading(false);
}
if (run.status === 'COMPLETED' && run.output) {
callback({
url: new URL(run.output),
isRandom: false,
router,
});
setIsLoading(false);
setOpen(false);
}
}, [run?.status]);
useEffect(() => {
// Reset
setIsLoading(false);
setOpen(true);
setAttempt(1);
}, [runId, publicAccessToken]);
function constructText() {
if (!run) {
return 'Decrypting link...';
}
if (error) {
return 'Decryption submission error.';
}
if (run?.status === 'FAILED') {
return 'Link cannot not be decrypted.';
}
if (run?.status === 'COMPLETED') {
return 'Link decrypted successfully.';
}
return `Attempt ${attempt} of 3`;
}
return (
<Dialog onOpenChange={(o) => setOpen(o)} open={open}>
<DialogContent className="max-w-[75%] lg:max-w-[50%]">
<DialogHeader>
<DialogTitle>Link Decryption</DialogTitle>
<DialogDescription>
Please wait while we decrypt the link. This may take a few seconds.
</DialogDescription>
</DialogHeader>
{isLoading && (
<div className="w-full">
<LoaderCircle className="mx-auto size-24 animate-spin" />
</div>
)}
<Input
disabled
value={constructText()}
className={twMerge(
error || run?.status === 'FAILED'
? 'text-destructive-foreground bg-destructive'
: '',
'disabled:opacity-100'
)}
/>
<DialogFooter>
<Button variant="destructive" onClick={() => setOpen(false)}>
Cancel
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
works (do not import ``)
import { LoaderCircle } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { twMerge } from 'tailwind-merge';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import type { OpenLinkOptions } from '../types/OpenLinkOptions';
type Props = {
runId: string;
publicAccessToken: string;
callback: (options: OpenLinkOptions) => void;
};
export const DecryptionLoadingDialog = ({
runId,
publicAccessToken,
callback,
}: Props) => {
const router = useRouter();
const [open, setOpen] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [attempt, setAttempt] = useState(1);
const { run, error } = {
run: {
status: 'QUEUED',
output: 'https://www.google.com',
},
error: null,
}; // Replace with actual data fetching logic
useEffect(() => {
if (!run) return;
console.log('🚀 ~ run:', run);
if (run.status === 'QUEUED') {
setIsLoading(true);
}
if (run.status === 'REATTEMPTING') {
setAttempt((prev) => prev + 1);
}
if (run.status === 'FAILED' || run.status === 'COMPLETED') {
setIsLoading(false);
}
if (run.status === 'COMPLETED' && run.output) {
try {
callback({
url: new URL(run.output),
isRandom: false,
router,
});
} catch (e) {
console.error('Error parsing output URL:', e);
}
setIsLoading(false);
setOpen(false);
}
}, [run?.status]);
useEffect(() => {
// Reset
setIsLoading(false);
setOpen(true);
setAttempt(1);
}, [runId, publicAccessToken]);
function constructText() {
if (!run) {
return 'Decrypting link...';
}
if (error) {
return 'Decryption submission error.';
}
if (run?.status === 'FAILED') {
return 'Link cannot not be decrypted.';
}
if (run?.status === 'COMPLETED') {
return 'Link decrypted successfully.';
}
return `Attempt ${attempt} of 3`;
}
return (
<Dialog onOpenChange={(o) => setOpen(o)} open={open}>
<DialogContent className="max-w-[75%] lg:max-w-[50%]">
<DialogHeader>
<DialogTitle>Link Decryption</DialogTitle>
<DialogDescription>
Please wait while we decrypt the link. This may take a few seconds.
</DialogDescription>
</DialogHeader>
{isLoading && (
<div className="w-full">
<LoaderCircle className="mx-auto size-24 animate-spin" />
</div>
)}
<Input
disabled
value={constructText()}
className={twMerge(
error || run?.status === 'FAILED'
? 'text-destructive-foreground bg-destructive'
: '',
'disabled:opacity-100'
)}
/>
<DialogFooter>
<Button variant="destructive" onClick={() => setOpen(false)}>
Cancel
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
Additional information
using: 4.0.0-v4-beta.21
nextjs version: 14.2.30
error:
Uncaught Error: Class extends value [object Object] is not a constructor or null
React 15
workLoop webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:256
flushWork webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:225
performWorkUntilDeadline webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:534
EventHandlerNonNull* webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:569
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:630
NextJS 4
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/index.js:4
NextJS 4
React 2
NextJS 4
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/index.js:32
NextJS 4
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/client.js:3
NextJS 4
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-index.js:15
NextJS 4
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-next-dev.js:9
appBootstrap webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-bootstrap.js:57
loadScriptsInSequence webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-bootstrap.js:23
appBootstrap webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-bootstrap.js:56
<anonymous> webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-next-dev.js:8
NextJS 9
react-dom.development.js:17497:1
Metadata
Metadata
Assignees
Labels
No labels