From 43184791545bbf6fe8a840de07616fca8f3b7f97 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 17 Nov 2023 15:54:25 +0100 Subject: [PATCH] fix: Prevent errors in JSON storage when data is invalid --- src/storage/keyvalue/JsonResourceStorage.ts | 11 +++++++++-- .../unit/storage/keyvalue/JsonResourceStorage.test.ts | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/storage/keyvalue/JsonResourceStorage.ts b/src/storage/keyvalue/JsonResourceStorage.ts index 26e5ce844..71aa0903d 100644 --- a/src/storage/keyvalue/JsonResourceStorage.ts +++ b/src/storage/keyvalue/JsonResourceStorage.ts @@ -2,6 +2,7 @@ import { BasicRepresentation } from '../../http/representation/BasicRepresentati import type { Representation } from '../../http/representation/Representation'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { getLoggerFor } from '../../logging/LogUtil'; +import { createErrorMessage } from '../../util/errors/ErrorUtil'; import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError'; import { ensureTrailingSlash, isContainerIdentifier, joinUrl, trimLeadingSlashes } from '../../util/PathUtil'; import { readableToString } from '../../util/StreamUtil'; @@ -88,8 +89,14 @@ export class JsonResourceStorage implements KeyValueStorage { yield* this.getResourceEntries({ path }); } } else { - const json = JSON.parse(await readableToString(representation.data)) as T; - yield [ this.identifierToKey(identifier), json ]; + try { + const json = JSON.parse(await readableToString(representation.data)) as T; + yield [ this.identifierToKey(identifier), json ]; + } catch (error: unknown) { + this.logger.error(`Unable to parse ${identifier.path + }. You should probably delete this resource manually. Error: ${ + createErrorMessage(error)}`); + } } } } diff --git a/test/unit/storage/keyvalue/JsonResourceStorage.test.ts b/test/unit/storage/keyvalue/JsonResourceStorage.test.ts index 15ce4e915..038e3f1ef 100644 --- a/test/unit/storage/keyvalue/JsonResourceStorage.test.ts +++ b/test/unit/storage/keyvalue/JsonResourceStorage.test.ts @@ -5,7 +5,7 @@ import type { ResourceIdentifier } from '../../../../src/http/representation/Res import { JsonResourceStorage } from '../../../../src/storage/keyvalue/JsonResourceStorage'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError'; -import { isContainerIdentifier } from '../../../../src/util/PathUtil'; +import { isContainerIdentifier, joinUrl } from '../../../../src/util/PathUtil'; import { readableToString } from '../../../../src/util/StreamUtil'; import { LDP } from '../../../../src/util/Vocabularies'; @@ -112,6 +112,9 @@ describe('A JsonResourceStorage', (): void => { data.set(containerIdentifier, ''); data.set(subContainerIdentifier, ''); + // Manually setting invalid data which will be ignored + data.set(joinUrl(containerIdentifier, 'badData'), 'invalid JSON'); + const entries = []; for await (const entry of storage.entries()) { entries.push(entry);