UploadThing: Image upload successful, but reaching neither onUploadError nor onUploadSuccess
This used to work for some time, but today it stopped working
UploadThingError: Something went wrong. Please report this to UploadThing.
at INTERNAL_DO_NOT_USE__fatalClientError (index.js:494:52)
at __useUploadThingInternal.useEvent[startUpload] (button-client-DpQoAqtf.js:243:119)Caused by: TypeError: Cannot read properties of undefined (reading 'recipeImageId')
at useRecipeImagesContext.useUploadThing [as onClientUploadComplete] (C:\Users\rolan\WebstormProjects\pomegranate\app\(protected)\(subscription)\me\recipes\_components\RecipeContextV2\useRecipeImagesContext.ts:61:38)
at __useUploadThingInternal.useEvent[startUpload] (button-client-DpQoAqtf.js:231:221)
UploadThingError: Something went wrong. Please report this to UploadThing.
at INTERNAL_DO_NOT_USE__fatalClientError (index.js:494:52)
at __useUploadThingInternal.useEvent[startUpload] (button-client-DpQoAqtf.js:243:119)Caused by: TypeError: Cannot read properties of undefined (reading 'recipeImageId')
at useRecipeImagesContext.useUploadThing [as onClientUploadComplete] (C:\Users\rolan\WebstormProjects\pomegranate\app\(protected)\(subscription)\me\recipes\_components\RecipeContextV2\useRecipeImagesContext.ts:61:38)
at __useUploadThingInternal.useEvent[startUpload] (button-client-DpQoAqtf.js:231:221)
1 Reply
Server-side
onUploadError
or onUploadSuccess
is never reached, but onClientUploadComplete is, and serverData is undefined.
// uploadthing image upload
const { startUpload } = useUploadThing("recipeImage", {
onUploadBegin: () => setDirtyImageOrder(true),
onUploadError: handleUploadError,
onClientUploadComplete: (images) => {
for (const image of images) {
console.log(image.serverData);
// serverData is undefined!!!
imageUploadCompleted(
image.serverData.recipeImageId,
image.key,
);
router.prefetch(buildImageUrl(image.key));
}
},
});
// uploadthing image upload
const { startUpload } = useUploadThing("recipeImage", {
onUploadBegin: () => setDirtyImageOrder(true),
onUploadError: handleUploadError,
onClientUploadComplete: (images) => {
for (const image of images) {
console.log(image.serverData);
// serverData is undefined!!!
imageUploadCompleted(
image.serverData.recipeImageId,
image.key,
);
router.prefetch(buildImageUrl(image.key));
}
},
});
// Execute upload new images (if recipe is already available, otherwise procrastinate)
useEffect(() => {
if (!recipe) {
return;
}
if (!images.filter((image) => image.status === RecipeImageStatus.VALIDATING).length) {
return;
}
for (const image of images) {
if (
image.status === RecipeImageStatus.VALIDATING
&& image.file
) {
const handleError = () => {
// This is onUploadError
notifications.show(t("Failed uploading image."), {
key: "failed-recipe-image-upload",
severity: "error",
// Can auto-close because image is visually marked as errored
autoHideDuration: 3000,
});
setImages((prevState) =>
prevState.map((prevImage) => ({
...prevImage,
status: prevImage.id === image.id
? RecipeImageStatus.FAILED
: image.status,
}))
);
};
// Execute upload new images (if recipe is already available, otherwise procrastinate)
useEffect(() => {
if (!recipe) {
return;
}
if (!images.filter((image) => image.status === RecipeImageStatus.VALIDATING).length) {
return;
}
for (const image of images) {
if (
image.status === RecipeImageStatus.VALIDATING
&& image.file
) {
const handleError = () => {
// This is onUploadError
notifications.show(t("Failed uploading image."), {
key: "failed-recipe-image-upload",
severity: "error",
// Can auto-close because image is visually marked as errored
autoHideDuration: 3000,
});
setImages((prevState) =>
prevState.map((prevImage) => ({
...prevImage,
status: prevImage.id === image.id
? RecipeImageStatus.FAILED
: image.status,
}))
);
};
compressImages({
images: [image.file],
options: {
maxSizeMB: 2,
},
}).then((blobs) => {
const blob = blobs.shift();
if (blob && image.file) {
const compressedImage = new File([blob], image.file.name, { type: blob.type });
return startUpload([compressedImage], {
recipeId: recipe.id,
clientImageId: image.id,
});
}
}).then((data) => {
if (!data) {
handleError();
}
}).catch(handleError);
}
}
// Update image status
setImages((prevState) => prevState.map((image) => ({
...image,
status: image.status === RecipeImageStatus.VALIDATING && image.file
? RecipeImageStatus.UPLOADING
: image.status,
})));
}, [recipe, images]);
// Mark recipeImage as upload completed and assign fileKey
const imageUploadCompleted = (id: string, fileKey: string) => {
setImages((prevState) => prevState.map((image) => {
if (image.id === id) {
return {
...image,
fileKey: fileKey,
status: RecipeImageStatus.COMPLETED,
};
}
return image;
}));
};
compressImages({
images: [image.file],
options: {
maxSizeMB: 2,
},
}).then((blobs) => {
const blob = blobs.shift();
if (blob && image.file) {
const compressedImage = new File([blob], image.file.name, { type: blob.type });
return startUpload([compressedImage], {
recipeId: recipe.id,
clientImageId: image.id,
});
}
}).then((data) => {
if (!data) {
handleError();
}
}).catch(handleError);
}
}
// Update image status
setImages((prevState) => prevState.map((image) => ({
...image,
status: image.status === RecipeImageStatus.VALIDATING && image.file
? RecipeImageStatus.UPLOADING
: image.status,
})));
}, [recipe, images]);
// Mark recipeImage as upload completed and assign fileKey
const imageUploadCompleted = (id: string, fileKey: string) => {
setImages((prevState) => prevState.map((image) => {
if (image.id === id) {
return {
...image,
fileKey: fileKey,
status: RecipeImageStatus.COMPLETED,
};
}
return image;
}));
};