UT: Issues with completion callback in dev
Everything is working fine in production, but I'm unable to get the onComplete callbacks to work properly in dev.
I think I'm getting close, but I got the following error in console. I reached out to support via email, but I linked this thread since its a bit easier to communicate and share code via discord opposed to email.
Error:
Client side:
core:
I think I'm getting close, but I got the following error in console. I reached out to support via email, but I linked this thread since its a bit easier to communicate and share code via discord opposed to email.
Error:
Something went wrong. Please contact UploadThing and provide the following cause: "TypeError: records[0].serverData is undefined"Something went wrong. Please contact UploadThing and provide the following cause: "TypeError: records[0].serverData is undefined"Client side:
const { startUpload, isUploading } = useUploadThing('inputSource', {
onClientUploadComplete: (records) => {
const { url, type, uid } = records[0].serverData as {
url: string;
type: 'IMAGE' | 'VIDEO';
uid: number;
};
addUploadedInputSource(url, type, uid);
},
onUploadError: (error: Error) => {
console.error('error uploading input source', error);
toast.error('Error uploading file');
},
});const { startUpload, isUploading } = useUploadThing('inputSource', {
onClientUploadComplete: (records) => {
const { url, type, uid } = records[0].serverData as {
url: string;
type: 'IMAGE' | 'VIDEO';
uid: number;
};
addUploadedInputSource(url, type, uid);
},
onUploadError: (error: Error) => {
console.error('error uploading input source', error);
toast.error('Error uploading file');
},
});core:
export const uploadRouter = {
inputSource: f(
{
'image/jpeg': {
maxFileSize: '128KB',
maxFileCount: 1,
additionalProperties: {
width: 640,
height: 480,
},
},
},
{ awaitServerData: true },
)
.middleware(async () => {
const session = await auth();
console.log('session', session);
const uid = (
session.sessionClaims?.publicMetadata as { uid: number | undefined }
)?.uid;
if (!session.userId || !uid) throw new UploadThingError('UNAUTHORIZED');
return { uid };
})
.onUploadComplete(async ({ metadata, file }) => {
const { error: inputSourceError } = await tryCatch(
prisma.inputSource.create({
data: {
url: file.ufsUrl,
type: 'IMAGE',
uid: metadata.uid,
key: file.key,
},
}),
);
if (inputSourceError) {
throw new UploadThingError(
'failed to create input source: ' + inputSourceError.message,
);
}
revalidateTag(`input-sources-${metadata.uid}`);
return {
url: file.ufsUrl,
type: 'IMAGE',
uid: metadata.uid,
};
}),
} satisfies FileRouter;export const uploadRouter = {
inputSource: f(
{
'image/jpeg': {
maxFileSize: '128KB',
maxFileCount: 1,
additionalProperties: {
width: 640,
height: 480,
},
},
},
{ awaitServerData: true },
)
.middleware(async () => {
const session = await auth();
console.log('session', session);
const uid = (
session.sessionClaims?.publicMetadata as { uid: number | undefined }
)?.uid;
if (!session.userId || !uid) throw new UploadThingError('UNAUTHORIZED');
return { uid };
})
.onUploadComplete(async ({ metadata, file }) => {
const { error: inputSourceError } = await tryCatch(
prisma.inputSource.create({
data: {
url: file.ufsUrl,
type: 'IMAGE',
uid: metadata.uid,
key: file.key,
},
}),
);
if (inputSourceError) {
throw new UploadThingError(
'failed to create input source: ' + inputSourceError.message,
);
}
revalidateTag(`input-sources-${metadata.uid}`);
return {
url: file.ufsUrl,
type: 'IMAGE',
uid: metadata.uid,
};
}),
} satisfies FileRouter;