Improve error logging for photo uploads
This commit is contained in:
parent
ebbf01c698
commit
33a950f73c
@ -8,6 +8,7 @@ import {
|
|||||||
AI_TEXT_GENERATION_ENABLED,
|
AI_TEXT_GENERATION_ENABLED,
|
||||||
BLUR_ENABLED,
|
BLUR_ENABLED,
|
||||||
} from '@/site/config';
|
} from '@/site/config';
|
||||||
|
import ErrorNote from '@/components/ErrorNote';
|
||||||
|
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
@ -23,16 +24,19 @@ export default async function UploadPage({ params }: Params) {
|
|||||||
photoFormExif,
|
photoFormExif,
|
||||||
imageResizedBase64: imageThumbnailBase64,
|
imageResizedBase64: imageThumbnailBase64,
|
||||||
shouldStripGpsData,
|
shouldStripGpsData,
|
||||||
|
error,
|
||||||
} = await extractImageDataFromBlobPath(uploadPath, {
|
} = await extractImageDataFromBlobPath(uploadPath, {
|
||||||
includeInitialPhotoFields: true,
|
includeInitialPhotoFields: true,
|
||||||
generateBlurData: BLUR_ENABLED,
|
generateBlurData: BLUR_ENABLED,
|
||||||
generateResizedImage: AI_TEXT_GENERATION_ENABLED,
|
generateResizedImage: AI_TEXT_GENERATION_ENABLED,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
const isDataMissing =
|
||||||
!photoFormExif ||
|
!photoFormExif ||
|
||||||
(AI_TEXT_GENERATION_ENABLED && !imageThumbnailBase64)
|
(AI_TEXT_GENERATION_ENABLED && !imageThumbnailBase64);
|
||||||
) {
|
|
||||||
|
if (isDataMissing && !error) {
|
||||||
|
// Only redirect if there's no error to report
|
||||||
redirect(PATH_ADMIN);
|
redirect(PATH_ADMIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,14 +47,18 @@ export default async function UploadPage({ params }: Params) {
|
|||||||
const textFieldsToAutoGenerate = AI_TEXT_AUTO_GENERATED_FIELDS;
|
const textFieldsToAutoGenerate = AI_TEXT_AUTO_GENERATED_FIELDS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UploadPageClient {...{
|
!isDataMissing
|
||||||
blobId,
|
? <UploadPageClient {...{
|
||||||
photoFormExif,
|
blobId,
|
||||||
uniqueTags,
|
photoFormExif,
|
||||||
hasAiTextGeneration,
|
uniqueTags,
|
||||||
textFieldsToAutoGenerate,
|
hasAiTextGeneration,
|
||||||
imageThumbnailBase64,
|
textFieldsToAutoGenerate,
|
||||||
shouldStripGpsData,
|
imageThumbnailBase64,
|
||||||
}} />
|
shouldStripGpsData,
|
||||||
|
}} />
|
||||||
|
: <ErrorNote>
|
||||||
|
{error ?? 'Unknown error'}
|
||||||
|
</ErrorNote>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -29,6 +29,7 @@ export const extractImageDataFromBlobPath = async (
|
|||||||
imageResizedBase64?: string
|
imageResizedBase64?: string
|
||||||
shouldStripGpsData?: boolean
|
shouldStripGpsData?: boolean
|
||||||
fileBytes?: ArrayBuffer
|
fileBytes?: ArrayBuffer
|
||||||
|
error?: string
|
||||||
}> => {
|
}> => {
|
||||||
const {
|
const {
|
||||||
includeInitialPhotoFields,
|
includeInitialPhotoFields,
|
||||||
@ -42,49 +43,60 @@ export const extractImageDataFromBlobPath = async (
|
|||||||
|
|
||||||
const extension = getExtensionFromStorageUrl(url);
|
const extension = getExtensionFromStorageUrl(url);
|
||||||
|
|
||||||
const fileBytes = blobPath
|
|
||||||
? await fetch(url, { cache: 'no-store' }).then(res => res.arrayBuffer())
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
let exifData: ExifData | undefined;
|
let exifData: ExifData | undefined;
|
||||||
let filmSimulation: FilmSimulation | undefined;
|
let filmSimulation: FilmSimulation | undefined;
|
||||||
let blurData: string | undefined;
|
let blurData: string | undefined;
|
||||||
let imageResizedBase64: string | undefined;
|
let imageResizedBase64: string | undefined;
|
||||||
let shouldStripGpsData = false;
|
let shouldStripGpsData = false;
|
||||||
|
let error: string | undefined;
|
||||||
|
|
||||||
if (fileBytes) {
|
const fileBytes = blobPath
|
||||||
const parser = ExifParserFactory.create(Buffer.from(fileBytes));
|
? await fetch(url, { cache: 'no-store' }).then(res => res.arrayBuffer())
|
||||||
|
.catch(e => {
|
||||||
|
error = `Error fetching image from ${url}: "${e.message}"`;
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
// Data for form
|
try {
|
||||||
parser.enableBinaryFields(false);
|
if (fileBytes) {
|
||||||
exifData = parser.parse();
|
const parser = ExifParserFactory.create(Buffer.from(fileBytes));
|
||||||
|
|
||||||
// Capture film simulation for Fujifilm cameras
|
// Data for form
|
||||||
if (isExifForFujifilm(exifData)) {
|
parser.enableBinaryFields(false);
|
||||||
// Parse exif data again with binary fields
|
exifData = parser.parse();
|
||||||
// in order to access MakerNote tag
|
|
||||||
parser.enableBinaryFields(true);
|
// Capture film simulation for Fujifilm cameras
|
||||||
const exifDataBinary = parser.parse();
|
if (isExifForFujifilm(exifData)) {
|
||||||
const makerNote = exifDataBinary.tags?.MakerNote;
|
// Parse exif data again with binary fields
|
||||||
if (Buffer.isBuffer(makerNote)) {
|
// in order to access MakerNote tag
|
||||||
filmSimulation = getFujifilmSimulationFromMakerNote(makerNote);
|
parser.enableBinaryFields(true);
|
||||||
|
const exifDataBinary = parser.parse();
|
||||||
|
const makerNote = exifDataBinary.tags?.MakerNote;
|
||||||
|
if (Buffer.isBuffer(makerNote)) {
|
||||||
|
filmSimulation = getFujifilmSimulationFromMakerNote(makerNote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (generateBlurData) {
|
if (generateBlurData) {
|
||||||
blurData = await blurImage(fileBytes);
|
blurData = await blurImage(fileBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateResizedImage) {
|
if (generateResizedImage) {
|
||||||
imageResizedBase64 = await resizeImage(fileBytes);
|
imageResizedBase64 = await resizeImage(fileBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldStripGpsData = GEO_PRIVACY_ENABLED && (
|
shouldStripGpsData = GEO_PRIVACY_ENABLED && (
|
||||||
Boolean(exifData.tags?.GPSLatitude) ||
|
Boolean(exifData.tags?.GPSLatitude) ||
|
||||||
Boolean(exifData.tags?.GPSLongitude)
|
Boolean(exifData.tags?.GPSLongitude)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
error = `Error extracting image data from ${url}: "${e}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error) { console.log(error); }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blobId,
|
blobId,
|
||||||
...exifData && {
|
...exifData && {
|
||||||
@ -102,6 +114,7 @@ export const extractImageDataFromBlobPath = async (
|
|||||||
imageResizedBase64,
|
imageResizedBase64,
|
||||||
shouldStripGpsData,
|
shouldStripGpsData,
|
||||||
fileBytes,
|
fileBytes,
|
||||||
|
error,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user