diff --git a/CHANGELOG.md b/CHANGELOG.md index f23e1af95..be6630ae1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Resolved an exception in the portfolio details endpoint when an asset profile is unmatched + ## 3.3.0 - 2026-05-14 ### Added diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 60b413cf9..ade683d41 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -36,7 +36,12 @@ import { TAG_ID_EXCLUDE_FROM_ANALYSIS, UNKNOWN_KEY } from '@ghostfolio/common/config'; -import { DATE_FORMAT, getSum, parseDate } from '@ghostfolio/common/helper'; +import { + DATE_FORMAT, + getAssetProfileIdentifier, + getSum, + parseDate +} from '@ghostfolio/common/helper'; import { AccountsResponse, Activity, @@ -64,7 +69,7 @@ import { } from '@ghostfolio/common/types'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; -import { Inject, Injectable } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { Account, @@ -558,9 +563,17 @@ export class PortfolioService { const cashSymbolProfiles = this.getCashSymbolProfiles(cashDetails); symbolProfiles.push(...cashSymbolProfiles); - const symbolProfileMap: { [symbol: string]: EnhancedSymbolProfile } = {}; + const symbolProfileMap: { + [assetProfileIdentifier: string]: EnhancedSymbolProfile; + } = {}; + for (const symbolProfile of symbolProfiles) { - symbolProfileMap[symbolProfile.symbol] = symbolProfile; + symbolProfileMap[ + getAssetProfileIdentifier({ + dataSource: symbolProfile.dataSource, + symbol: symbolProfile.symbol + }) + ] = symbolProfile; } const portfolioItemsNow: { [symbol: string]: TimelinePosition } = {}; @@ -571,6 +584,7 @@ export class PortfolioService { for (const { activitiesCount, currency, + dataSource, dateOfFirstActivity, dividend, grossPerformance, @@ -600,7 +614,17 @@ export class PortfolioService { } } - const assetProfile = symbolProfileMap[symbol]; + const assetProfile = + symbolProfileMap[getAssetProfileIdentifier({ dataSource, symbol })]; + + if (!assetProfile) { + Logger.warn( + `Asset profile not found for ${symbol} (${dataSource})`, + 'PortfolioService' + ); + + continue; + } let markets: PortfolioPosition['markets']; let marketsAdvanced: PortfolioPosition['marketsAdvanced'];