diff --git a/server/src/nest/memories/photo-capture-backfill.service.ts b/server/src/nest/memories/photo-capture-backfill.service.ts index c7dc958c9..08fec55c9 100644 --- a/server/src/nest/memories/photo-capture-backfill.service.ts +++ b/server/src/nest/memories/photo-capture-backfill.service.ts @@ -2,7 +2,7 @@ import { TrekPhotoRegistrationService } from '../photos/trek-photo-registration. import { StorageService } from '../storage/storage.service'; import { exifCaptureInstant } from './memories.helpers'; import { PhotoResolverService } from './photo-resolver.service'; -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import exifr from 'exifr'; @@ -95,6 +95,8 @@ interface LookupSlots { */ @Injectable() export class PhotoCaptureBackfillService { + private readonly logger = new Logger(PhotoCaptureBackfillService.name); + /** * Open lookups per user, never above BACKFILL_CONCURRENCY for any of them. An * entry lives only while its user has a lookup open or waiting, so the map @@ -234,7 +236,7 @@ export class PhotoCaptureBackfillService { }); return changed ? 'changed' : 'same'; } catch (err) { - console.error(`[Photos] capture reconfirm failed for ${id}:`, err instanceof Error ? err.message : err); + this.logger.warn(`capture reconfirm failed for ${id}: ${err instanceof Error ? err.message : String(err)}`); return 'failed'; } } diff --git a/server/tests/unit/nest/photo-capture-backfill.service.test.ts b/server/tests/unit/nest/photo-capture-backfill.service.test.ts index 91d7460fe..bebb4bffd 100644 --- a/server/tests/unit/nest/photo-capture-backfill.service.test.ts +++ b/server/tests/unit/nest/photo-capture-backfill.service.test.ts @@ -31,17 +31,24 @@ type Row = { lng?: number | null; }; -function build(rows: Row[], info: Record) { +function build( + rows: Row[], + info: Record, + extra: { getPhotoInfo?: (...args: unknown[]) => Promise; photos?: Record } = {}, +) { const recordCaptureMetadata = vi.fn(); // Keyed on the SECOND argument on purpose: the resolver's signature is // (userId, photoId), and a mock that keys on the first one passes just as // happily when the two are swapped at the call site. - const getPhotoInfo = vi.fn(async (_userId: number, id: number) => - info[id] ? { success: true, data: info[id] } : { success: false, error: 'nope', status: 404 }, + const getPhotoInfo = vi.fn( + extra.getPhotoInfo ?? + (async (_userId: number, id: number) => + info[id] ? { success: true, data: info[id] } : { success: false, error: 'nope', status: 404 }), ); const photos = { resolve: (id: number) => rows.find((r) => r.id === id) ?? null, recordCaptureMetadata, + ...extra.photos, } as unknown as TrekPhotoRegistrationService; const resolver = { getPhotoInfo } as unknown as PhotoResolverService; return { svc: new PhotoCaptureBackfillService(resolver, photos, storageStub), recordCaptureMetadata, getPhotoInfo }; @@ -527,13 +534,7 @@ describe('PhotoCaptureBackfillService — local files', () => { describe('PhotoCaptureBackfillService.reconfirm', () => { function buildReconfirm(answer: () => Promise, changed = true) { const replaceCaptureMetadata = vi.fn(async () => changed); - const getPhotoInfo = vi.fn(answer); - const photos = { replaceCaptureMetadata } as unknown as TrekPhotoRegistrationService; - const svc = new PhotoCaptureBackfillService( - { getPhotoInfo } as unknown as PhotoResolverService, - photos, - storageStub, - ); + const { svc, getPhotoInfo } = build([], {}, { getPhotoInfo: answer, photos: { replaceCaptureMetadata } }); return { svc, replaceCaptureMetadata, getPhotoInfo }; } @@ -560,11 +561,10 @@ describe('PhotoCaptureBackfillService.reconfirm', () => { expect(await unconfirmed.svc.reconfirm(7, 3)).toBe('failed'); expect(unconfirmed.replaceCaptureMetadata).not.toHaveBeenCalled(); - const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const throwing = buildReconfirm(async () => { throw new Error('NAS gone'); }); expect(await throwing.svc.reconfirm(7, 3)).toBe('failed'); - errSpy.mockRestore(); + expect(throwing.replaceCaptureMetadata).not.toHaveBeenCalled(); }); });