mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
fix(core): handle image-blob reduce errors more gracefully (#14056)
This PR is related to issue https://github.com/toeverything/AFFiNE/issues/14018 When uploading a new profile photo avatar the Pica function, which is responsible for reducing and resizing the profile photo, may crash if the browser's Fingerprint Protection is enabled. This is because Fingerprint Protection prevents Pica from modifying the canvas. This fix introduces a try-catch inside the function that calls the reduction and resizing of the photo. Also, the Error object is no longer passed directly to the notification service, which also caused issues previously. Now a message will appear that tells the user that the upload failed and to check the browser's fingerprint protection (check photo below). Affected files: packages/frontend/core/src/utils/reduce-image.ts <img width="408" height="136" alt="new_error" src="https://github.com/user-attachments/assets/d140e17c-8c13-4f4b-bdf7-7dd5ddc5c917" /> I'm open to any suggestions in terms of wording of the error messages. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved error handling for image compression with clearer, user-facing messages when compression is blocked or fails. * Ensures the original or reduced image is reliably returned as a fallback if compression is not performed. * Preserves file metadata (original lastModified, name, type) when returning processed files. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <darksky2048@gmail.com> Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
This commit is contained in:
@@ -20,23 +20,33 @@ export const validateAndReduceImage = async (file: File): Promise<File> => {
|
||||
const sizeInMB = file.size / (1024 * 1024);
|
||||
if (sizeInMB > 10 || img.width > 4000 || img.height > 4000) {
|
||||
// Compress the file to less than 10MB
|
||||
const compressedImg = await reduce().toBlob(file, {
|
||||
max: 4000,
|
||||
unsharpAmount: 80,
|
||||
unsharpRadius: 0.6,
|
||||
unsharpThreshold: 2,
|
||||
});
|
||||
return compressedImg;
|
||||
|
||||
try {
|
||||
const compressedImg = await reduce().toBlob(file, {
|
||||
max: 4000,
|
||||
unsharpAmount: 80,
|
||||
unsharpRadius: 0.6,
|
||||
unsharpThreshold: 2,
|
||||
});
|
||||
return compressedImg;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(
|
||||
'Image processing failed. This can happen if fingerprint protection is enabled in your browser. Please check your browser settings and try again.'
|
||||
);
|
||||
} else {
|
||||
throw new Error('Unknown error occurred');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
};
|
||||
|
||||
try {
|
||||
const reducedBlob = await decodeAndReduceImage();
|
||||
const reducedBlob = await decodeAndReduceImage();
|
||||
|
||||
return new File([reducedBlob], file.name, { type: file.type });
|
||||
} catch (error) {
|
||||
throw new Error('Image could not be reduce :' + error);
|
||||
}
|
||||
return new File([reducedBlob], file.name, {
|
||||
type: file.type,
|
||||
lastModified: file.lastModified,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user