From aa753d0146fe6f3746e0872e12c68ab6a5516f48 Mon Sep 17 00:00:00 2001 From: Rene Turcios <95189389+CloudCorpRecords@users.noreply.github.com> Date: Sat, 17 Oct 2026 14:31:24 -0700 Subject: [PATCH] fix(api): return value unchanged in toCurrency for null currencies Prevents 'No exchange rate has been found for nullEUR' error logs when toCurrency is called with a null or undefined source or target currency (e.g. an account without a currency set). Fixes ghostfolio/ghostfolio#6168 Signed-off-by: Rene Turcios <95189389+CloudCorpRecords@users.noreply.github.com> --- .../exchange-rate-data.service.spec.ts | 42 +++++++++++++++++++ .../exchange-rate-data.service.ts | 7 ++++ 2 files changed, 49 insertions(+) create mode 100644 apps/api/src/services/exchange-rate-data/exchange-rate-data.service.spec.ts diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.spec.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.spec.ts new file mode 100644 index 0000000000..1245ecc54d --- /dev/null +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.spec.ts @@ -0,0 +1,42 @@ +import { ExchangeRateDataService } from './exchange-rate-data.service'; + +describe('ExchangeRateDataService', () => { + let service: ExchangeRateDataService; + + beforeEach(() => { + service = new ExchangeRateDataService(null, null, null, null); + }); + + describe('toCurrency', () => { + it('should return the value unchanged for a null source currency without logging an error', () => { + const loggerSpy = jest.spyOn(service['logger'], 'error'); + + const result = service.toCurrency(100, null as any, 'EUR'); + + expect(result).toEqual(100); + expect(loggerSpy).not.toHaveBeenCalled(); + }); + + it('should return the value unchanged for an undefined source currency without logging an error', () => { + const loggerSpy = jest.spyOn(service['logger'], 'error'); + + const result = service.toCurrency(100, undefined as any, 'EUR'); + + expect(result).toEqual(100); + expect(loggerSpy).not.toHaveBeenCalled(); + }); + + it('should return the value unchanged for a null target currency without logging an error', () => { + const loggerSpy = jest.spyOn(service['logger'], 'error'); + + const result = service.toCurrency(100, 'EUR', null as any); + + expect(result).toEqual(100); + expect(loggerSpy).not.toHaveBeenCalled(); + }); + + it('should return 0 for a value of 0', () => { + expect(service.toCurrency(0, 'USD', 'EUR')).toEqual(0); + }); + }); +}); diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index b68ed2fb15..62e8c97598 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -257,6 +257,13 @@ export class ExchangeRateDataService { return 0; } + if (!aFromCurrency || !aToCurrency) { + // The currency of the value is unknown (e.g. an account without a + // currency), so no conversion can be performed. Return the value + // unchanged instead of logging an error for a "null" currency. + return aValue; + } + let factor: number; if (aFromCurrency === aToCurrency) {