Browse Source

Improve currency validation

pull/5747/head
Thomas Kaul 3 weeks ago
parent
commit
428c80a9b3
  1. 10
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts
  2. 20
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts
  3. 14
      apps/api/src/services/data-provider/data-provider.service.ts
  4. 7
      apps/api/src/services/data-provider/errors/asset-profile-invalid.error.ts
  5. 4
      apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

10
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts

@ -1,5 +1,6 @@
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { AssetProfileInvalidError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-invalid.error';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { import {
DataProviderGhostfolioAssetProfileResponse, DataProviderGhostfolioAssetProfileResponse,
@ -66,7 +67,14 @@ export class GhostfolioController {
}); });
return assetProfile; return assetProfile;
} catch { } catch (error) {
if (error instanceof AssetProfileInvalidError) {
throw new HttpException(
getReasonPhrase(StatusCodes.NOT_FOUND),
StatusCodes.NOT_FOUND
);
}
throw new HttpException( throw new HttpException(
getReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR), getReasonPhrase(StatusCodes.INTERNAL_SERVER_ERROR),
StatusCodes.INTERNAL_SERVER_ERROR StatusCodes.INTERNAL_SERVER_ERROR

20
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts

@ -40,10 +40,7 @@ export class GhostfolioService {
private readonly propertyService: PropertyService private readonly propertyService: PropertyService
) {} ) {}
public async getAssetProfile({ public async getAssetProfile({ symbol }: GetAssetProfileParams) {
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbol
}: GetAssetProfileParams) {
let result: DataProviderGhostfolioAssetProfileResponse = {}; let result: DataProviderGhostfolioAssetProfileResponse = {};
try { try {
@ -51,12 +48,15 @@ export class GhostfolioService {
for (const dataProviderService of this.getDataProviderServices()) { for (const dataProviderService of this.getDataProviderServices()) {
promises.push( promises.push(
dataProviderService this.dataProviderService
.getAssetProfile({ .getAssetProfiles([
requestTimeout, {
symbol symbol,
}) dataSource: dataProviderService.getName()
.then(async (assetProfile) => { }
])
.then(async (assetProfiles) => {
const assetProfile = assetProfiles[symbol];
const dataSourceOrigin = DataSource.GHOSTFOLIO; const dataSourceOrigin = DataSource.GHOSTFOLIO;
if (assetProfile) { if (assetProfile) {

14
apps/api/src/services/data-provider/data-provider.service.ts

@ -35,6 +35,8 @@ import { eachDayOfInterval, format, isValid } from 'date-fns';
import { groupBy, isEmpty, isNumber, uniqWith } from 'lodash'; import { groupBy, isEmpty, isNumber, uniqWith } from 'lodash';
import ms from 'ms'; import ms from 'ms';
import { AssetProfileInvalidError } from './errors/asset-profile-invalid.error';
@Injectable() @Injectable()
export class DataProviderService implements OnModuleInit { export class DataProviderService implements OnModuleInit {
private dataProviderMapping: { [dataProviderName: string]: string }; private dataProviderMapping: { [dataProviderName: string]: string };
@ -106,9 +108,9 @@ export class DataProviderService implements OnModuleInit {
); );
promises.push( promises.push(
promise.then((symbolProfile) => { promise.then((assetProfile) => {
if (symbolProfile) { if (isCurrency(assetProfile?.currency)) {
response[symbol] = symbolProfile; response[symbol] = assetProfile;
} }
}) })
); );
@ -117,6 +119,12 @@ export class DataProviderService implements OnModuleInit {
try { try {
await Promise.all(promises); await Promise.all(promises);
if (isEmpty(response)) {
throw new AssetProfileInvalidError(
'No valid asset profiles have been found'
);
}
} catch (error) { } catch (error) {
Logger.error(error, 'DataProviderService'); Logger.error(error, 'DataProviderService');

7
apps/api/src/services/data-provider/errors/asset-profile-invalid.error.ts

@ -0,0 +1,7 @@
export class AssetProfileInvalidError extends Error {
public constructor(message: string) {
super(message);
this.name = 'AssetProfileInvalidError';
}
}

4
apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

@ -102,6 +102,10 @@ export class FinancialModelingPrepService implements DataProviderInterface {
} }
).then((res) => res.json()); ).then((res) => res.json());
if (!assetProfile) {
throw new Error(`${symbol} not found`);
}
const { assetClass, assetSubClass } = const { assetClass, assetSubClass } =
this.parseAssetClass(assetProfile); this.parseAssetClass(assetProfile);

Loading…
Cancel
Save