feat(server): include reason in null reverse geocoding logs (#20347)

* Clarify in log why reverse geocoding may return nothing

* Decrease log level for empty reverse geocoding response from warn to log

* Use a named constant for 25km

* Mention fallback to countries in the message

* Improve natural earth log message

* Decrease log level for empty reverse geocoding response from natural earth countries
This commit is contained in:
Sergey Katsubo 2025-07-28 16:51:00 +03:00 committed by GitHub
parent 1e1c2ea627
commit d34670bae6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 7 additions and 6 deletions

View File

@ -55,6 +55,7 @@ export const MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME = Number(
); );
export const citiesFile = 'cities500.txt'; export const citiesFile = 'cities500.txt';
export const reverseGeocodeMaxDistance = 25_000;
export const MOBILE_REDIRECT = 'app.immich:///oauth-callback'; export const MOBILE_REDIRECT = 'app.immich:///oauth-callback';
export const LOGIN_URL = '/auth/login?autoLaunch=0'; export const LOGIN_URL = '/auth/login?autoLaunch=0';

View File

@ -5,7 +5,7 @@ import { InjectKysely } from 'nestjs-kysely';
import { createReadStream, existsSync } from 'node:fs'; import { createReadStream, existsSync } from 'node:fs';
import { readFile } from 'node:fs/promises'; import { readFile } from 'node:fs/promises';
import readLine from 'node:readline'; import readLine from 'node:readline';
import { citiesFile } from 'src/constants'; import { citiesFile, reverseGeocodeMaxDistance } from 'src/constants';
import { DummyValue, GenerateSql } from 'src/decorators'; import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetVisibility, SystemMetadataKey } from 'src/enum'; import { AssetVisibility, SystemMetadataKey } from 'src/enum';
import { ConfigRepository } from 'src/repositories/config.repository'; import { ConfigRepository } from 'src/repositories/config.repository';
@ -145,7 +145,7 @@ export class MapRepository {
.selectFrom('geodata_places') .selectFrom('geodata_places')
.selectAll() .selectAll()
.where( .where(
sql`earth_box(ll_to_earth_public(${point.latitude}, ${point.longitude}), 25000)`, sql`earth_box(ll_to_earth_public(${point.latitude}, ${point.longitude}), ${reverseGeocodeMaxDistance})`,
'@>', '@>',
sql`ll_to_earth_public(latitude, longitude)`, sql`ll_to_earth_public(latitude, longitude)`,
) )
@ -165,8 +165,8 @@ export class MapRepository {
return { country, state, city }; return { country, state, city };
} }
this.logger.warn( this.logger.log(
`Response from database for reverse geocoding latitude: ${point.latitude}, longitude: ${point.longitude} was null`, `Empty response from database for city reverse geocoding lat: ${point.latitude}, lon: ${point.longitude}. Likely cause: no nearby large populated place (500+ within ${reverseGeocodeMaxDistance / 1000}km). Falling back to country boundaries.`,
); );
const ne_response = await this.db const ne_response = await this.db
@ -177,8 +177,8 @@ export class MapRepository {
.executeTakeFirst(); .executeTakeFirst();
if (!ne_response) { if (!ne_response) {
this.logger.warn( this.logger.log(
`Response from database for natural earth reverse geocoding latitude: ${point.latitude}, longitude: ${point.longitude} was null`, `Empty response from database for natural earth country reverse geocoding lat: ${point.latitude}, lon: ${point.longitude}`,
); );
return { country: null, state: null, city: null }; return { country: null, state: null, city: null };