From af8f1976cdf083c4dd5da33a146fa4b613bce815 Mon Sep 17 00:00:00 2001 From: Ruben Verborgh Date: Fri, 27 Nov 2020 10:25:05 +0100 Subject: [PATCH] fix: Rename UnsupportedHttpError into BadRequestError. --- index.ts | 2 +- src/ldp/http/BasicResponseWriter.ts | 4 +-- src/ldp/http/ErrorResponseWriter.ts | 4 +-- src/ldp/http/RawBodyParser.ts | 4 +-- src/ldp/http/SparqlUpdateBodyParser.ts | 6 ++-- src/ldp/http/metadata/SlugParser.ts | 4 +-- src/ldp/operations/DeleteOperationHandler.ts | 4 +-- src/ldp/operations/GetOperationHandler.ts | 4 +-- src/ldp/operations/HeadOperationHandler.ts | 4 +-- src/ldp/operations/PatchOperationHandler.ts | 4 +-- src/ldp/operations/PostOperationHandler.ts | 7 ++-- src/ldp/operations/PutOperationHandler.ts | 7 ++-- .../permissions/MethodPermissionsExtractor.ts | 4 +-- .../SparqlPatchPermissionsExtractor.ts | 10 +++--- src/storage/DataAccessorBasedStore.ts | 10 +++--- src/storage/RoutingResourceStore.ts | 4 +-- src/storage/accessors/DataAccessor.ts | 4 +-- src/storage/accessors/SparqlDataAccessor.ts | 4 +-- src/storage/conversion/ConversionUtil.ts | 15 ++++---- src/storage/conversion/RdfToQuadConverter.ts | 4 +-- src/storage/mapping/ExtensionBasedMapper.ts | 6 ++-- src/storage/mapping/FixedContentTypeMapper.ts | 4 +-- src/storage/mapping/MapperUtil.ts | 8 ++--- src/storage/patch/SparqlUpdatePatchHandler.ts | 12 +++---- src/storage/routing/RegexRouterRule.ts | 7 ++-- src/util/FirstCompositeHandler.ts | 4 +-- src/util/HeaderUtil.ts | 36 +++++++++---------- ...tedHttpError.ts => BadRequestHttpError.ts} | 4 +-- ...tedError.ts => NotImplementedHttpError.ts} | 4 +-- .../unit/ldp/http/BasicResponseWriter.test.ts | 6 ++-- .../unit/ldp/http/ErrorResponseWriter.test.ts | 8 ++--- .../ldp/http/SparqlUpdateBodyParser.test.ts | 6 ++-- .../unit/ldp/http/metadata/SlugParser.test.ts | 4 +-- .../operations/DeleteOperationHandler.test.ts | 4 +-- .../operations/GetOperationHandler.test.ts | 4 +-- .../operations/HeadOperationHandler.test.ts | 6 ++-- .../operations/PatchOperationHandler.test.ts | 4 +-- .../operations/PostOperationHandler.test.ts | 7 ++-- .../operations/PutOperationHandler.test.ts | 7 ++-- .../BasePermissionsExtractor.test.ts | 4 +-- .../SparqlPatchPermissionsExtractor.test.ts | 10 +++--- .../storage/DataAccessorBasedStore.test.ts | 18 +++++----- .../unit/storage/RoutingResourceStore.test.ts | 4 +-- .../accessors/SparqlDataAccessor.test.ts | 4 +-- .../storage/conversion/ConversionUtil.test.ts | 4 +-- .../conversion/RdfToQuadConverter.test.ts | 6 ++-- .../mapping/ExtensionBasedMapper.test.ts | 10 +++--- .../mapping/FixedContentTypeMapper.test.ts | 8 ++--- .../patch/SparqlUpdatePatchHandler.test.ts | 4 +-- .../storage/routing/PreferenceSupport.test.ts | 4 +-- .../storage/routing/RegexRouterRule.test.ts | 6 ++-- test/unit/util/FirstCompositeHandler.test.ts | 6 ++-- ...or.test.ts => BadRequestHttpError.test.ts} | 10 +++--- 53 files changed, 177 insertions(+), 171 deletions(-) rename src/util/errors/{UnsupportedHttpError.ts => BadRequestHttpError.ts} (69%) rename src/util/errors/{NotImplementedError.ts => NotImplementedHttpError.ts} (72%) rename test/unit/util/errors/{UnsupportedHttpError.test.ts => BadRequestHttpError.test.ts} (53%) diff --git a/index.ts b/index.ts index eb3801d70..489c3ad94 100644 --- a/index.ts +++ b/index.ts @@ -134,6 +134,7 @@ export * from './src/storage/ResourceStore'; export * from './src/storage/RoutingResourceStore'; // Util/Errors +export * from './src/util/errors/BadRequestHttpError'; export * from './src/util/errors/ConflictHttpError'; export * from './src/util/errors/ForbiddenHttpError'; export * from './src/util/errors/HttpError'; @@ -141,7 +142,6 @@ export * from './src/util/errors/MethodNotAllowedHttpError'; export * from './src/util/errors/NotFoundHttpError'; export * from './src/util/errors/SystemError'; export * from './src/util/errors/UnauthorizedHttpError'; -export * from './src/util/errors/UnsupportedHttpError'; export * from './src/util/errors/UnsupportedMediaTypeHttpError'; // Util/Locking diff --git a/src/ldp/http/BasicResponseWriter.ts b/src/ldp/http/BasicResponseWriter.ts index 2e75a66a6..eef69a2d8 100644 --- a/src/ldp/http/BasicResponseWriter.ts +++ b/src/ldp/http/BasicResponseWriter.ts @@ -1,7 +1,7 @@ import { getLoggerFor } from '../../logging/LogUtil'; import type { HttpResponse } from '../../server/HttpResponse'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { pipeSafely } from '../../util/StreamUtil'; import type { MetadataWriter } from './metadata/MetadataWriter'; import type { ResponseDescription } from './response/ResponseDescription'; @@ -22,7 +22,7 @@ export class BasicResponseWriter extends ResponseWriter { public async canHandle(input: { response: HttpResponse; result: ResponseDescription | Error }): Promise { if (input.result instanceof Error || input.result.metadata?.contentType === INTERNAL_QUADS) { this.logger.warn('This writer only supports binary ResponseDescriptions'); - throw new UnsupportedHttpError('Only successful binary responses are supported'); + throw new NotImplementedHttpError('Only successful binary responses are supported'); } } diff --git a/src/ldp/http/ErrorResponseWriter.ts b/src/ldp/http/ErrorResponseWriter.ts index 43705ccb9..226f1a52b 100644 --- a/src/ldp/http/ErrorResponseWriter.ts +++ b/src/ldp/http/ErrorResponseWriter.ts @@ -1,7 +1,7 @@ import { getLoggerFor } from '../../logging/LogUtil'; import type { HttpResponse } from '../../server/HttpResponse'; import { HttpError } from '../../util/errors/HttpError'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import type { ResponseDescription } from './response/ResponseDescription'; import { ResponseWriter } from './ResponseWriter'; @@ -14,7 +14,7 @@ export class ErrorResponseWriter extends ResponseWriter { public async canHandle(input: { response: HttpResponse; result: ResponseDescription | Error }): Promise { if (!(input.result instanceof Error)) { this.logger.warn('This writer can only write errors'); - throw new UnsupportedHttpError('Only errors are supported'); + throw new NotImplementedHttpError('Only errors are supported'); } } diff --git a/src/ldp/http/RawBodyParser.ts b/src/ldp/http/RawBodyParser.ts index 4b893260d..a05bbeb71 100644 --- a/src/ldp/http/RawBodyParser.ts +++ b/src/ldp/http/RawBodyParser.ts @@ -1,5 +1,5 @@ import { getLoggerFor } from '../../logging/LogUtil'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import type { Representation } from '../representation/Representation'; import type { BodyParserArgs } from './BodyParser'; import { BodyParser } from './BodyParser'; @@ -24,7 +24,7 @@ export class RawBodyParser extends BodyParser { // such an omission likely signals a mistake, so force clients to make this explicit. if (!request.headers['content-type']) { this.logger.warn('A body was passed, but the content length was not specified'); - throw new UnsupportedHttpError('HTTP request body was passed without Content-Type header'); + throw new BadRequestHttpError('HTTP request body was passed without Content-Type header'); } return { diff --git a/src/ldp/http/SparqlUpdateBodyParser.ts b/src/ldp/http/SparqlUpdateBodyParser.ts index 225f8ab9f..8f5244b01 100644 --- a/src/ldp/http/SparqlUpdateBodyParser.ts +++ b/src/ldp/http/SparqlUpdateBodyParser.ts @@ -3,7 +3,7 @@ import type { Algebra } from 'sparqlalgebrajs'; import { translate } from 'sparqlalgebrajs'; import { getLoggerFor } from '../../logging/LogUtil'; import { APPLICATION_SPARQL_UPDATE } from '../../util/ContentTypes'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError'; import { pipeSafely, readableToString } from '../../util/StreamUtil'; import type { BodyParserArgs } from './BodyParser'; @@ -36,9 +36,9 @@ export class SparqlUpdateBodyParser extends BodyParser { } catch (error: unknown) { this.logger.warn('Could not translate SPARQL query to SPARQL algebra', { error }); if (error instanceof Error) { - throw new UnsupportedHttpError(error.message); + throw new BadRequestHttpError(error.message); } - throw new UnsupportedHttpError(); + throw new BadRequestHttpError(); } // Prevent body from being requested again diff --git a/src/ldp/http/metadata/SlugParser.ts b/src/ldp/http/metadata/SlugParser.ts index 1bd82b53b..cf895a093 100644 --- a/src/ldp/http/metadata/SlugParser.ts +++ b/src/ldp/http/metadata/SlugParser.ts @@ -1,6 +1,6 @@ import { getLoggerFor } from '../../../logging/LogUtil'; import type { HttpRequest } from '../../../server/HttpRequest'; -import { UnsupportedHttpError } from '../../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../util/errors/BadRequestHttpError'; import { HTTP } from '../../../util/UriConstants'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; import type { MetadataParser } from './MetadataParser'; @@ -16,7 +16,7 @@ export class SlugParser implements MetadataParser { if (slug) { if (Array.isArray(slug)) { this.logger.warn(`Expected 0 or 1 Slug headers but received ${slug.length}`); - throw new UnsupportedHttpError('Request has multiple Slug headers'); + throw new BadRequestHttpError('Request has multiple Slug headers'); } this.logger.debug(`Request Slug is '${slug}'.`); metadata.set(HTTP.slug, slug); diff --git a/src/ldp/operations/DeleteOperationHandler.ts b/src/ldp/operations/DeleteOperationHandler.ts index f27020c1a..03685c73e 100644 --- a/src/ldp/operations/DeleteOperationHandler.ts +++ b/src/ldp/operations/DeleteOperationHandler.ts @@ -1,5 +1,5 @@ import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { ResetResponseDescription } from '../http/response/ResetResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; import type { Operation } from './Operation'; @@ -19,7 +19,7 @@ export class DeleteOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'DELETE') { - throw new UnsupportedHttpError('This handler only supports DELETE operations'); + throw new NotImplementedHttpError('This handler only supports DELETE operations'); } } diff --git a/src/ldp/operations/GetOperationHandler.ts b/src/ldp/operations/GetOperationHandler.ts index 636977a26..3055a58c7 100644 --- a/src/ldp/operations/GetOperationHandler.ts +++ b/src/ldp/operations/GetOperationHandler.ts @@ -1,5 +1,5 @@ import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { OkResponseDescription } from '../http/response/OkResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; import type { Operation } from './Operation'; @@ -19,7 +19,7 @@ export class GetOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'GET') { - throw new UnsupportedHttpError('This handler only supports GET operations'); + throw new NotImplementedHttpError('This handler only supports GET operations'); } } diff --git a/src/ldp/operations/HeadOperationHandler.ts b/src/ldp/operations/HeadOperationHandler.ts index 1af5722eb..7a49393b7 100644 --- a/src/ldp/operations/HeadOperationHandler.ts +++ b/src/ldp/operations/HeadOperationHandler.ts @@ -1,5 +1,5 @@ import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { OkResponseDescription } from '../http/response/OkResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; import type { Operation } from './Operation'; @@ -19,7 +19,7 @@ export class HeadOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'HEAD') { - throw new UnsupportedHttpError('This handler only supports HEAD operations'); + throw new NotImplementedHttpError('This handler only supports HEAD operations'); } } diff --git a/src/ldp/operations/PatchOperationHandler.ts b/src/ldp/operations/PatchOperationHandler.ts index b46178479..a4a1ee954 100644 --- a/src/ldp/operations/PatchOperationHandler.ts +++ b/src/ldp/operations/PatchOperationHandler.ts @@ -1,5 +1,5 @@ import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import type { Patch } from '../http/Patch'; import { ResetResponseDescription } from '../http/response/ResetResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; @@ -16,7 +16,7 @@ export class PatchOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'PATCH') { - throw new UnsupportedHttpError('This handler only supports PATCH operations.'); + throw new NotImplementedHttpError('This handler only supports PATCH operations.'); } } diff --git a/src/ldp/operations/PostOperationHandler.ts b/src/ldp/operations/PostOperationHandler.ts index 07f07200d..9b9de16f3 100644 --- a/src/ldp/operations/PostOperationHandler.ts +++ b/src/ldp/operations/PostOperationHandler.ts @@ -1,6 +1,7 @@ import { getLoggerFor } from '../../logging/LogUtil'; import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { CreatedResponseDescription } from '../http/response/CreatedResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; import type { Operation } from './Operation'; @@ -22,14 +23,14 @@ export class PostOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'POST') { - throw new UnsupportedHttpError('This handler only supports POST operations'); + throw new NotImplementedHttpError('This handler only supports POST operations'); } } public async handle(input: Operation): Promise { if (!input.body) { this.logger.warn('POST operations require a body'); - throw new UnsupportedHttpError('POST operations require a body'); + throw new BadRequestHttpError('POST operations require a body'); } const identifier = await this.store.addResource(input.target, input.body); return new CreatedResponseDescription(identifier); diff --git a/src/ldp/operations/PutOperationHandler.ts b/src/ldp/operations/PutOperationHandler.ts index d530c98b5..7cdede505 100644 --- a/src/ldp/operations/PutOperationHandler.ts +++ b/src/ldp/operations/PutOperationHandler.ts @@ -1,6 +1,7 @@ import { getLoggerFor } from '../../logging/LogUtil'; import type { ResourceStore } from '../../storage/ResourceStore'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { ResetResponseDescription } from '../http/response/ResetResponseDescription'; import type { ResponseDescription } from '../http/response/ResponseDescription'; import type { Operation } from './Operation'; @@ -22,14 +23,14 @@ export class PutOperationHandler extends OperationHandler { public async canHandle(input: Operation): Promise { if (input.method !== 'PUT') { - throw new UnsupportedHttpError('This handler only supports PUT operations'); + throw new NotImplementedHttpError('This handler only supports PUT operations'); } } public async handle(input: Operation): Promise { if (typeof input.body !== 'object') { this.logger.warn('No body specified on PUT request'); - throw new UnsupportedHttpError('PUT operations require a body'); + throw new BadRequestHttpError('PUT operations require a body'); } await this.store.setRepresentation(input.target, input.body); return new ResetResponseDescription(); diff --git a/src/ldp/permissions/MethodPermissionsExtractor.ts b/src/ldp/permissions/MethodPermissionsExtractor.ts index 96bdd1f37..59e69e649 100644 --- a/src/ldp/permissions/MethodPermissionsExtractor.ts +++ b/src/ldp/permissions/MethodPermissionsExtractor.ts @@ -1,5 +1,5 @@ import { getLoggerFor } from '../../logging/LogUtil'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import type { Operation } from '../operations/Operation'; import type { PermissionSet } from './PermissionSet'; import { PermissionsExtractor } from './PermissionsExtractor'; @@ -18,7 +18,7 @@ export class MethodPermissionsExtractor extends PermissionsExtractor { public async canHandle({ method }: Operation): Promise { if (!SUPPORTED_METHODS.has(method)) { this.logger.warn(`Unrecognized method ${method}`); - throw new UnsupportedHttpError(`Cannot determine permissions of ${method}`); + throw new NotImplementedHttpError(`Cannot determine permissions of ${method}`); } } diff --git a/src/ldp/permissions/SparqlPatchPermissionsExtractor.ts b/src/ldp/permissions/SparqlPatchPermissionsExtractor.ts index 22b3f3904..c4f1ab5b3 100644 --- a/src/ldp/permissions/SparqlPatchPermissionsExtractor.ts +++ b/src/ldp/permissions/SparqlPatchPermissionsExtractor.ts @@ -1,5 +1,5 @@ import { Algebra } from 'sparqlalgebrajs'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import type { SparqlUpdatePatch } from '../http/SparqlUpdatePatch'; import type { Operation } from '../operations/Operation'; import type { Representation } from '../representation/Representation'; @@ -14,16 +14,16 @@ import { PermissionsExtractor } from './PermissionsExtractor'; export class SparqlPatchPermissionsExtractor extends PermissionsExtractor { public async canHandle({ method, body }: Operation): Promise { if (method !== 'PATCH') { - throw new UnsupportedHttpError(`Cannot determine permissions of ${method}, only PATCH.`); + throw new NotImplementedHttpError(`Cannot determine permissions of ${method}, only PATCH.`); } if (!body) { - throw new UnsupportedHttpError('Cannot determine permissions of PATCH operations without a body.'); + throw new NotImplementedHttpError('Cannot determine permissions of PATCH operations without a body.'); } if (!this.isSparql(body)) { - throw new UnsupportedHttpError('Cannot determine permissions of non-SPARQL patches.'); + throw new NotImplementedHttpError('Cannot determine permissions of non-SPARQL patches.'); } if (!this.isDeleteInsert(body.algebra)) { - throw new UnsupportedHttpError('Cannot determine permissions of a PATCH without DELETE/INSERT.'); + throw new NotImplementedHttpError('Cannot determine permissions of a PATCH without DELETE/INSERT.'); } } diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index f2df21c9d..adf0f25da 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -6,11 +6,11 @@ import type { Representation } from '../ldp/representation/Representation'; import { RepresentationMetadata } from '../ldp/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier'; import { INTERNAL_QUADS } from '../util/ContentTypes'; +import { BadRequestHttpError } from '../util/errors/BadRequestHttpError'; import { ConflictHttpError } from '../util/errors/ConflictHttpError'; import { MethodNotAllowedHttpError } from '../util/errors/MethodNotAllowedHttpError'; import { NotFoundHttpError } from '../util/errors/NotFoundHttpError'; -import { NotImplementedError } from '../util/errors/NotImplementedError'; -import { UnsupportedHttpError } from '../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError'; import type { Guarded } from '../util/GuardedStream'; import { ensureTrailingSlash, @@ -136,7 +136,7 @@ export class DataAccessorBasedStore implements ResourceStore { throw new ConflictHttpError('Input resource type does not match existing resource type.'); } if (isContainer !== isContainerIdentifier(identifier)) { - throw new UnsupportedHttpError('Containers should have a `/` at the end of their path, resources should not.'); + throw new BadRequestHttpError('Containers should have a `/` at the end of their path, resources should not.'); } // Potentially have to create containers if it didn't exist yet @@ -144,7 +144,7 @@ export class DataAccessorBasedStore implements ResourceStore { } public async modifyResource(): Promise { - throw new NotImplementedError('Patches are not supported by the default store.'); + throw new NotImplementedHttpError('Patches are not supported by the default store.'); } public async deleteResource(identifier: ResourceIdentifier): Promise { @@ -246,7 +246,7 @@ export class DataAccessorBasedStore implements ResourceStore { quads = await parseQuads(representation.data); } catch (error: unknown) { if (error instanceof Error) { - throw new UnsupportedHttpError(`Can only create containers with RDF data. ${error.message}`); + throw new BadRequestHttpError(`Can only create containers with RDF data. ${error.message}`); } throw error; } diff --git a/src/storage/RoutingResourceStore.ts b/src/storage/RoutingResourceStore.ts index 190a2d9d6..56c37d4ff 100644 --- a/src/storage/RoutingResourceStore.ts +++ b/src/storage/RoutingResourceStore.ts @@ -3,7 +3,7 @@ import type { Representation } from '../ldp/representation/Representation'; import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences'; import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier'; import { NotFoundHttpError } from '../util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../util/errors/NotImplementedHttpError'; import type { Conditions } from './Conditions'; import type { ResourceStore } from './ResourceStore'; import type { RouterRule } from './routing/RouterRule'; @@ -53,7 +53,7 @@ export class RoutingResourceStore implements ResourceStore { try { return await this.rule.handleSafe({ identifier }); } catch (error: unknown) { - if (error instanceof UnsupportedHttpError) { + if (error instanceof NotImplementedHttpError) { throw new NotFoundHttpError(); } throw error; diff --git a/src/storage/accessors/DataAccessor.ts b/src/storage/accessors/DataAccessor.ts index 93b5618c8..ef793603c 100644 --- a/src/storage/accessors/DataAccessor.ts +++ b/src/storage/accessors/DataAccessor.ts @@ -15,10 +15,10 @@ import type { Guarded } from '../../util/GuardedStream'; */ export interface DataAccessor { /** - * Should throw an UnsupportedHttpError if the DataAccessor does not support storing the given Representation. + * Should throw a NotImplementedHttpError if the DataAccessor does not support storing the given Representation. * @param representation - Incoming Representation. * - * @throws UnsupportedHttpError + * @throws BadRequestHttpError * If it does not support the incoming data. */ canHandle: (representation: Representation) => Promise; diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index eb003ed8a..56970bfb1 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -21,7 +21,7 @@ import { getLoggerFor } from '../../logging/LogUtil'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; import { ConflictHttpError } from '../../util/errors/ConflictHttpError'; import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError'; import { guardStream } from '../../util/GuardedStream'; import type { Guarded } from '../../util/GuardedStream'; @@ -126,7 +126,7 @@ export class SparqlDataAccessor implements DataAccessor { const triples = await arrayifyStream(data) as Quad[]; const def = defaultGraph(); if (triples.some((triple): boolean => !def.equals(triple.graph))) { - throw new UnsupportedHttpError('Only triples in the default graph are supported.'); + throw new NotImplementedHttpError('Only triples in the default graph are supported.'); } // Not relevant since all content is triples diff --git a/src/storage/conversion/ConversionUtil.ts b/src/storage/conversion/ConversionUtil.ts index 9aac11769..592771fbb 100644 --- a/src/storage/conversion/ConversionUtil.ts +++ b/src/storage/conversion/ConversionUtil.ts @@ -1,8 +1,9 @@ import type { RepresentationPreference } from '../../ldp/representation/RepresentationPreference'; import type { RepresentationPreferences } from '../../ldp/representation/RepresentationPreferences'; import { INTERNAL_ALL } from '../../util/ContentTypes'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { InternalServerError } from '../../util/errors/InternalServerError'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import type { RepresentationConverterArgs } from './RepresentationConverter'; /** @@ -15,7 +16,7 @@ import type { RepresentationConverterArgs } from './RepresentationConverter'; * @param preferences - Preferences for output type. * @param types - Media types to compare to the preferences. * - * @throws UnsupportedHttpError + * @throws BadRequestHttpError * If the type preferences are undefined or if there are duplicate preferences. * * @returns The weighted and filtered list of matching types. @@ -23,12 +24,12 @@ import type { RepresentationConverterArgs } from './RepresentationConverter'; export const matchingTypes = (preferences: RepresentationPreferences, types: string[]): RepresentationPreference[] => { if (!Array.isArray(preferences.type)) { - throw new UnsupportedHttpError('Output type required for conversion.'); + throw new BadRequestHttpError('Output type required for conversion.'); } const prefMap = preferences.type.reduce((map: Record, pref): Record => { if (map[pref.value]) { - throw new UnsupportedHttpError(`Duplicate type preference found: ${pref.value}`); + throw new BadRequestHttpError(`Duplicate type preference found: ${pref.value}`); } map[pref.value] = pref.weight; return map; @@ -96,12 +97,12 @@ export const validateRequestArgs = (request: RepresentationConverterArgs, suppor supportedOut: string[]): void => { const inType = request.representation.metadata.contentType; if (!inType) { - throw new UnsupportedHttpError('Input type required for conversion.'); + throw new BadRequestHttpError('Input type required for conversion.'); } if (!supportedIn.some((type): boolean => matchingMediaType(inType, type))) { - throw new UnsupportedHttpError(`Can only convert from ${supportedIn} to ${supportedOut}.`); + throw new NotImplementedHttpError(`Can only convert from ${supportedIn} to ${supportedOut}.`); } if (matchingTypes(request.preferences, supportedOut).length <= 0) { - throw new UnsupportedHttpError(`Can only convert from ${supportedIn} to ${supportedOut}.`); + throw new NotImplementedHttpError(`Can only convert from ${supportedIn} to ${supportedOut}.`); } }; diff --git a/src/storage/conversion/RdfToQuadConverter.ts b/src/storage/conversion/RdfToQuadConverter.ts index ddfe3f6c2..80b8daca9 100644 --- a/src/storage/conversion/RdfToQuadConverter.ts +++ b/src/storage/conversion/RdfToQuadConverter.ts @@ -3,7 +3,7 @@ import rdfParser from 'rdf-parse'; import type { Representation } from '../../ldp/representation/Representation'; import { RepresentationMetadata } from '../../ldp/representation/RepresentationMetadata'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { pipeSafely } from '../../util/StreamUtil'; import { CONTENT_TYPE } from '../../util/UriConstants'; import { validateRequestArgs } from './ConversionUtil'; @@ -38,7 +38,7 @@ export class RdfToQuadConverter extends TypedRepresentationConverter { }); const pass = new PassThrough({ objectMode: true }); - const data = pipeSafely(rawQuads, pass, (error): Error => new UnsupportedHttpError(error.message)); + const data = pipeSafely(rawQuads, pass, (error): Error => new BadRequestHttpError(error.message)); return { binary: false, diff --git a/src/storage/mapping/ExtensionBasedMapper.ts b/src/storage/mapping/ExtensionBasedMapper.ts index 89badf876..012b48434 100644 --- a/src/storage/mapping/ExtensionBasedMapper.ts +++ b/src/storage/mapping/ExtensionBasedMapper.ts @@ -5,7 +5,7 @@ import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdenti import { getLoggerFor } from '../../logging/LogUtil'; import { APPLICATION_OCTET_STREAM, TEXT_TURTLE } from '../../util/ContentTypes'; import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { encodeUriPathComponents, ensureTrailingSlash, @@ -82,7 +82,7 @@ export class ExtensionBasedMapper implements FileIdentifierMapper { // Would conflict with how new extensions are stored if (/\$\.\w+$/u.test(filePath)) { this.logger.warn(`Identifier ${identifier.path} contains a dollar sign before its extension`); - throw new UnsupportedHttpError('Identifiers cannot contain a dollar sign before their extension'); + throw new NotImplementedHttpError('Identifiers cannot contain a dollar sign before their extension'); } // Existing file @@ -123,7 +123,7 @@ export class ExtensionBasedMapper implements FileIdentifierMapper { const extension = mime.extension(contentType); if (!extension) { this.logger.warn(`No extension found for ${contentType}`); - throw new UnsupportedHttpError(`Unsupported content type ${contentType}`); + throw new NotImplementedHttpError(`Unsupported content type ${contentType}`); } filePath += `$.${extension}`; } diff --git a/src/storage/mapping/FixedContentTypeMapper.ts b/src/storage/mapping/FixedContentTypeMapper.ts index 13ac6593f..8a62967cc 100644 --- a/src/storage/mapping/FixedContentTypeMapper.ts +++ b/src/storage/mapping/FixedContentTypeMapper.ts @@ -1,7 +1,7 @@ import { posix } from 'path'; import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier'; import { getLoggerFor } from '../../logging/LogUtil'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { encodeUriPathComponents, ensureTrailingSlash, isContainerIdentifier, @@ -45,7 +45,7 @@ export class FixedContentTypeMapper implements FileIdentifierMapper { // Only allow the configured content type if (contentType && contentType !== this.contentType) { - throw new UnsupportedHttpError(`Unsupported content type ${contentType}, only ${this.contentType} is allowed`); + throw new NotImplementedHttpError(`Unsupported content type ${contentType}, only ${this.contentType} is allowed`); } this.logger.info(`The path for ${identifier.path} is ${filePath}`); diff --git a/src/storage/mapping/MapperUtil.ts b/src/storage/mapping/MapperUtil.ts index e7da44846..e3e660f6e 100644 --- a/src/storage/mapping/MapperUtil.ts +++ b/src/storage/mapping/MapperUtil.ts @@ -1,8 +1,8 @@ import { posix } from 'path'; import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier'; import type { Logger } from '../../logging/Logger'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; import { decodeUriPathComponents } from '../../util/PathUtil'; const { join: joinPath } = posix; @@ -40,7 +40,7 @@ export const getRelativePath = (baseRequestURI: string, identifier: ResourceIden /** * Check if the given relative path is valid. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * If the relative path is invalid. * * @param path - A relative path, as generated by {@link getRelativePath}. @@ -50,11 +50,11 @@ export const getRelativePath = (baseRequestURI: string, identifier: ResourceIden export const validateRelativePath = (path: string, identifier: ResourceIdentifier, logger: Logger): void => { if (!path.startsWith('/')) { logger.warn(`URL ${identifier.path} needs a / after the base`); - throw new UnsupportedHttpError('URL needs a / after the base'); + throw new BadRequestHttpError('URL needs a / after the base'); } if (path.includes('/..')) { logger.warn(`Disallowed /.. segment in URL ${identifier.path}.`); - throw new UnsupportedHttpError('Disallowed /.. segment in URL'); + throw new BadRequestHttpError('Disallowed /.. segment in URL'); } }; diff --git a/src/storage/patch/SparqlUpdatePatchHandler.ts b/src/storage/patch/SparqlUpdatePatchHandler.ts index 9c5ff6ff1..28d337e40 100644 --- a/src/storage/patch/SparqlUpdatePatchHandler.ts +++ b/src/storage/patch/SparqlUpdatePatchHandler.ts @@ -10,7 +10,7 @@ import { RepresentationMetadata } from '../../ldp/representation/RepresentationM import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier'; import { getLoggerFor } from '../../logging/LogUtil'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { guardStream } from '../../util/GuardedStream'; import type { ResourceLocker } from '../../util/locking/ResourceLocker'; import { CONTENT_TYPE } from '../../util/UriConstants'; @@ -35,7 +35,7 @@ export class SparqlUpdatePatchHandler extends PatchHandler { public async canHandle(input: {identifier: ResourceIdentifier; patch: SparqlUpdatePatch}): Promise { if (typeof input.patch.algebra !== 'object') { - throw new UnsupportedHttpError('Only SPARQL update patch requests are supported'); + throw new NotImplementedHttpError('Only SPARQL update patch requests are supported'); } } @@ -43,7 +43,7 @@ export class SparqlUpdatePatchHandler extends PatchHandler { const op = input.patch.algebra; if (!this.isDeleteInsert(op)) { this.logger.warn(`Unsupported operation: ${op.type}`); - throw new UnsupportedHttpError('Only DELETE/INSERT SPARQL update operations are supported'); + throw new NotImplementedHttpError('Only DELETE/INSERT SPARQL update operations are supported'); } const def = defaultGraph(); @@ -52,16 +52,16 @@ export class SparqlUpdatePatchHandler extends PatchHandler { if (!deletes.every((pattern): boolean => pattern.graph.equals(def))) { this.logger.warn('GRAPH statement in DELETE clause'); - throw new UnsupportedHttpError('GRAPH statements are not supported'); + throw new NotImplementedHttpError('GRAPH statements are not supported'); } if (!inserts.every((pattern): boolean => pattern.graph.equals(def))) { this.logger.warn('GRAPH statement in INSERT clause'); - throw new UnsupportedHttpError('GRAPH statements are not supported'); + throw new NotImplementedHttpError('GRAPH statements are not supported'); } if (op.where ?? deletes.some((pattern): boolean => someTerms(pattern, (term): boolean => term.termType === 'Variable'))) { this.logger.warn('WHERE statements are not supported'); - throw new UnsupportedHttpError('WHERE statements are not supported'); + throw new NotImplementedHttpError('WHERE statements are not supported'); } const lock = await this.locker.acquire(input.identifier); diff --git a/src/storage/routing/RegexRouterRule.ts b/src/storage/routing/RegexRouterRule.ts index ebcb5eaf9..1494e14b1 100644 --- a/src/storage/routing/RegexRouterRule.ts +++ b/src/storage/routing/RegexRouterRule.ts @@ -1,6 +1,7 @@ import type { Representation } from '../../ldp/representation/Representation'; import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier'; -import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; +import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { trimTrailingSlashes } from '../../util/PathUtil'; import type { ResourceStore } from '../ResourceStore'; import { RouterRule } from './RouterRule'; @@ -47,7 +48,7 @@ export class RegexRouterRule extends RouterRule { return this.regexes.get(regex)!; } } - throw new UnsupportedHttpError(`No stored regexes match ${identifier.path}`); + throw new NotImplementedHttpError(`No stored regexes match ${identifier.path}`); } /** @@ -55,7 +56,7 @@ export class RegexRouterRule extends RouterRule { */ private toRelative(identifier: ResourceIdentifier): string { if (!identifier.path.startsWith(this.base)) { - throw new UnsupportedHttpError(`Identifiers need to start with ${this.base}`); + throw new BadRequestHttpError(`Identifiers need to start with ${this.base}`); } return identifier.path.slice(this.base.length); } diff --git a/src/util/FirstCompositeHandler.ts b/src/util/FirstCompositeHandler.ts index aa53c6aa1..4372650f6 100644 --- a/src/util/FirstCompositeHandler.ts +++ b/src/util/FirstCompositeHandler.ts @@ -1,8 +1,8 @@ import { getLoggerFor } from '../logging/LogUtil'; import type { AsyncHandler } from './AsyncHandler'; +import { BadRequestHttpError } from './errors/BadRequestHttpError'; import { HttpError } from './errors/HttpError'; import { InternalServerError } from './errors/InternalServerError'; -import { UnsupportedHttpError } from './errors/UnsupportedHttpError'; /** * Handler that combines several other handlers, @@ -106,6 +106,6 @@ export class FirstCompositeHandler implements AsyncHandler if (errors.some((error): boolean => error.statusCode >= 500)) { throw new InternalServerError(message); } - throw new UnsupportedHttpError(message); + throw new BadRequestHttpError(message); } } diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 0abe3ae02..f97c75197 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -1,6 +1,6 @@ import { getLoggerFor } from '../logging/LogUtil'; import type { HttpResponse } from '../server/HttpResponse'; -import { UnsupportedHttpError } from './errors/UnsupportedHttpError'; +import { BadRequestHttpError } from './errors/BadRequestHttpError'; const logger = getLoggerFor('HeaderUtil'); @@ -110,7 +110,7 @@ export const transformQuotedStrings = (input: string): { result: string; replace // Not all characters allowed in quoted strings, see BNF above if (!/^"(?:[\t !\u0023-\u005B\u005D-\u007E\u0080-\u00FF]|(?:\\[\t\u0020-\u007E\u0080-\u00FF]))*"$/u.test(match)) { logger.warn(`Invalid quoted string in header: ${match}`); - throw new UnsupportedHttpError(`Invalid quoted string in header: ${match}`); + throw new BadRequestHttpError(`Invalid quoted string in header: ${match}`); } const replacement = `"${idx}"`; replacements[replacement] = match.slice(1, -1); @@ -135,13 +135,13 @@ export const splitAndClean = (input: string): string[] => * * @param qvalue - Input qvalue string (so "q=...."). * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid syntax. */ const testQValue = (qvalue: string): void => { if (!/^(?:(?:0(?:\.\d{0,3})?)|(?:1(?:\.0{0,3})?))$/u.test(qvalue)) { logger.warn(`Invalid q value: ${qvalue}`); - throw new UnsupportedHttpError( + throw new BadRequestHttpError( `Invalid q value: ${qvalue} does not match ( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ).`, ); } @@ -154,7 +154,7 @@ const testQValue = (qvalue: string): void => { * @param replacements - The double quoted strings that need to be replaced. * * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid parameter syntax. * * @returns An array of name/value objects corresponding to the parameters. @@ -168,7 +168,7 @@ export const parseParameters = (parameters: string[], replacements: Record): Ac } else { if (!value && map !== extensionParams) { logger.warn(`Invalid Accept parameter ${name}`); - throw new UnsupportedHttpError(`Invalid Accept parameter ${name}: ` + + throw new BadRequestHttpError(`Invalid Accept parameter ${name}: ` + `Accept parameter values are not optional when preceding the q value`); } map[name] = value || ''; @@ -243,7 +243,7 @@ const parseAcceptPart = (part: string, replacements: Record): Ac * Parses an Accept-* header where each part is only a value and a weight, so roughly /.*(q=.*)?/ separated by commas. * @param input - Input header string. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid qvalue syntax. * * @returns An array of ranges and weights. @@ -257,7 +257,7 @@ const parseNoParameters = (input: string): { range: string; weight: number }[] = if (qvalue) { if (!qvalue.startsWith('q=')) { logger.warn(`Only q parameters are allowed in ${input}`); - throw new UnsupportedHttpError(`Only q parameters are allowed in ${input}`); + throw new BadRequestHttpError(`Only q parameters are allowed in ${input}`); } const val = qvalue.slice(2); testQValue(val); @@ -274,7 +274,7 @@ const parseNoParameters = (input: string): { range: string; weight: number }[] = * * @param input - The Accept header string. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid header syntax. * * @returns An array of {@link Accept} objects, sorted by weight. @@ -292,7 +292,7 @@ export const parseAccept = (input: string): Accept[] => { * * @param input - The Accept-Charset header string. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid header syntax. * * @returns An array of {@link AcceptCharset} objects, sorted by weight. @@ -302,7 +302,7 @@ export const parseAcceptCharset = (input: string): AcceptCharset[] => { results.forEach((result): void => { if (!token.test(result.range)) { logger.warn(`Invalid Accept-Charset range: ${result.range}`); - throw new UnsupportedHttpError( + throw new BadRequestHttpError( `Invalid Accept-Charset range: ${result.range} does not match (content-coding / "identity" / "*")`, ); } @@ -315,7 +315,7 @@ export const parseAcceptCharset = (input: string): AcceptCharset[] => { * * @param input - The Accept-Encoding header string. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid header syntax. * * @returns An array of {@link AcceptEncoding} objects, sorted by weight. @@ -325,7 +325,7 @@ export const parseAcceptEncoding = (input: string): AcceptEncoding[] => { results.forEach((result): void => { if (!token.test(result.range)) { logger.warn(`Invalid Accept-Encoding range: ${result.range}`); - throw new UnsupportedHttpError(`Invalid Accept-Encoding range: ${result.range} does not match (charset / "*")`); + throw new BadRequestHttpError(`Invalid Accept-Encoding range: ${result.range} does not match (charset / "*")`); } }); return results; @@ -336,7 +336,7 @@ export const parseAcceptEncoding = (input: string): AcceptEncoding[] => { * * @param input - The Accept-Language header string. * - * @throws {@link UnsupportedHttpError} + * @throws {@link BadRequestHttpError} * Thrown on invalid header syntax. * * @returns An array of {@link AcceptLanguage} objects, sorted by weight. @@ -349,7 +349,7 @@ export const parseAcceptLanguage = (input: string): AcceptLanguage[] => { logger.warn( `Invalid Accept-Language range: ${result.range}`, ); - throw new UnsupportedHttpError( + throw new BadRequestHttpError( `Invalid Accept-Language range: ${result.range} does not match ((1*8ALPHA *("-" 1*8alphanum)) / "*")`, ); } diff --git a/src/util/errors/UnsupportedHttpError.ts b/src/util/errors/BadRequestHttpError.ts similarity index 69% rename from src/util/errors/UnsupportedHttpError.ts rename to src/util/errors/BadRequestHttpError.ts index 22ecb2207..8b979861b 100644 --- a/src/util/errors/UnsupportedHttpError.ts +++ b/src/util/errors/BadRequestHttpError.ts @@ -4,12 +4,12 @@ import { HttpError } from './HttpError'; * An error thrown when incoming data is not supported. * Probably because an {@link AsyncHandler} returns false on the canHandle call. */ -export class UnsupportedHttpError extends HttpError { +export class BadRequestHttpError extends HttpError { /** * Default message is 'The given input is not supported by the server configuration.'. * @param message - Optional, more specific, message. */ public constructor(message?: string) { - super(400, 'UnsupportedHttpError', message ?? 'The given input is not supported by the server configuration.'); + super(400, 'BadRequestHttpError', message ?? 'The given input is not supported by the server configuration.'); } } diff --git a/src/util/errors/NotImplementedError.ts b/src/util/errors/NotImplementedHttpError.ts similarity index 72% rename from src/util/errors/NotImplementedError.ts rename to src/util/errors/NotImplementedHttpError.ts index dc617527d..1418c3d2c 100644 --- a/src/util/errors/NotImplementedError.ts +++ b/src/util/errors/NotImplementedHttpError.ts @@ -3,8 +3,8 @@ import { HttpError } from './HttpError'; * The server either does not recognize the request method, or it lacks the ability to fulfil the request. * Usually this implies future availability (e.g., a new feature of a web-service API). */ -export class NotImplementedError extends HttpError { +export class NotImplementedHttpError extends HttpError { public constructor(message?: string) { - super(501, 'NotImplementedError', message); + super(501, 'NotImplementedHttpError', message); } } diff --git a/test/unit/ldp/http/BasicResponseWriter.test.ts b/test/unit/ldp/http/BasicResponseWriter.test.ts index 65899ceb3..33328287b 100644 --- a/test/unit/ldp/http/BasicResponseWriter.test.ts +++ b/test/unit/ldp/http/BasicResponseWriter.test.ts @@ -7,7 +7,7 @@ import type { MetadataWriter } from '../../../../src/ldp/http/metadata/MetadataW import type { ResponseDescription } from '../../../../src/ldp/http/response/ResponseDescription'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; import { guardedStreamFrom } from '../../../../src/util/StreamUtil'; import { CONTENT_TYPE } from '../../../../src/util/UriConstants'; import { StaticAsyncHandler } from '../../../util/StaticAsyncHandler'; @@ -27,10 +27,10 @@ describe('A BasicResponseWriter', (): void => { it('requires the input to be a binary ResponseDescription.', async(): Promise => { await expect(writer.canHandle({ response, result: new Error('error') })) - .rejects.toThrow(UnsupportedHttpError); + .rejects.toThrow(NotImplementedHttpError); const metadata = new RepresentationMetadata({ [CONTENT_TYPE]: INTERNAL_QUADS }); await expect(writer.canHandle({ response, result: { statusCode: 201, metadata }})) - .rejects.toThrow(UnsupportedHttpError); + .rejects.toThrow(NotImplementedHttpError); await expect(writer.canHandle({ response, result })) .resolves.toBeUndefined(); }); diff --git a/test/unit/ldp/http/ErrorResponseWriter.test.ts b/test/unit/ldp/http/ErrorResponseWriter.test.ts index 0a4028b9b..1a7efe1d5 100644 --- a/test/unit/ldp/http/ErrorResponseWriter.test.ts +++ b/test/unit/ldp/http/ErrorResponseWriter.test.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'events'; import type { MockResponse } from 'node-mocks-http'; import { createResponse } from 'node-mocks-http'; import { ErrorResponseWriter } from '../../../../src/ldp/http/ErrorResponseWriter'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('An ErrorResponseWriter', (): void => { const writer = new ErrorResponseWriter(); @@ -16,7 +16,7 @@ describe('An ErrorResponseWriter', (): void => { await expect(writer.canHandle({ response, result: new Error('error') })) .resolves.toBeUndefined(); await expect(writer.canHandle({ response, result: { statusCode: 200 }})) - .rejects.toThrow(UnsupportedHttpError); + .rejects.toThrow(NotImplementedHttpError); }); it('responds with 500 if an error if there is an error.', async(): Promise => { @@ -27,11 +27,11 @@ describe('An ErrorResponseWriter', (): void => { }); it('responds with the given statuscode if there is an HttpError.', async(): Promise => { - const error = new UnsupportedHttpError('error'); + const error = new NotImplementedHttpError('error'); await writer.handle({ response, result: error }); expect(response._isEndCalled()).toBeTruthy(); expect(response._getStatusCode()).toBe(error.statusCode); - expect(response._getData()).toMatch('UnsupportedHttpError: error'); + expect(response._getData()).toMatch('NotImplementedHttpError: error'); }); it('responds with the error name and message when no stack trace is lazily generated.', async(): Promise => { diff --git a/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts b/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts index 5731f6d1e..264bb741c 100644 --- a/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts +++ b/test/unit/ldp/http/SparqlUpdateBodyParser.test.ts @@ -7,7 +7,7 @@ import type { BodyParserArgs } from '../../../../src/ldp/http/BodyParser'; import { SparqlUpdateBodyParser } from '../../../../src/ldp/http/SparqlUpdateBodyParser'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import type { HttpRequest } from '../../../../src/server/HttpRequest'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { UnsupportedMediaTypeHttpError } from '../../../../src/util/errors/UnsupportedMediaTypeHttpError'; describe('A SparqlUpdateBodyParser', (): void => { @@ -28,7 +28,7 @@ describe('A SparqlUpdateBodyParser', (): void => { it('errors when handling invalid SPARQL updates.', async(): Promise => { input.request = streamifyArray([ 'VERY INVALID UPDATE' ]) as HttpRequest; - await expect(bodyParser.handle(input)).rejects.toThrow(UnsupportedHttpError); + await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError); }); it('errors when receiving an unexpected error.', async(): Promise => { @@ -38,7 +38,7 @@ describe('A SparqlUpdateBodyParser', (): void => { input.request = streamifyArray( [ 'DELETE DATA { }' ], ) as HttpRequest; - await expect(bodyParser.handle(input)).rejects.toThrow(UnsupportedHttpError); + await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError); mock.mockRestore(); }); diff --git a/test/unit/ldp/http/metadata/SlugParser.test.ts b/test/unit/ldp/http/metadata/SlugParser.test.ts index 31d0fb178..93a1c3035 100644 --- a/test/unit/ldp/http/metadata/SlugParser.test.ts +++ b/test/unit/ldp/http/metadata/SlugParser.test.ts @@ -1,7 +1,7 @@ import { SlugParser } from '../../../../../src/ldp/http/metadata/SlugParser'; import { RepresentationMetadata } from '../../../../../src/ldp/representation/RepresentationMetadata'; import type { HttpRequest } from '../../../../../src/server/HttpRequest'; -import { UnsupportedHttpError } from '../../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../../src/util/errors/BadRequestHttpError'; import { HTTP } from '../../../../../src/util/UriConstants'; describe('A SlugParser', (): void => { @@ -22,7 +22,7 @@ describe('A SlugParser', (): void => { it('errors if there are multiple slug headers.', async(): Promise => { request.headers.slug = [ 'slugA', 'slugB' ]; await expect(parser.parse(request, metadata)) - .rejects.toThrow(new UnsupportedHttpError('Request has multiple Slug headers')); + .rejects.toThrow(new BadRequestHttpError('Request has multiple Slug headers')); }); it('stores the slug metadata.', async(): Promise => { diff --git a/test/unit/ldp/operations/DeleteOperationHandler.test.ts b/test/unit/ldp/operations/DeleteOperationHandler.test.ts index b603b9c30..a979c7ba6 100644 --- a/test/unit/ldp/operations/DeleteOperationHandler.test.ts +++ b/test/unit/ldp/operations/DeleteOperationHandler.test.ts @@ -1,7 +1,7 @@ import { DeleteOperationHandler } from '../../../../src/ldp/operations/DeleteOperationHandler'; import type { Operation } from '../../../../src/ldp/operations/Operation'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A DeleteOperationHandler', (): void => { const store = {} as unknown as ResourceStore; @@ -12,7 +12,7 @@ describe('A DeleteOperationHandler', (): void => { it('only supports DELETE operations.', async(): Promise => { await expect(handler.canHandle({ method: 'DELETE' } as Operation)).resolves.toBeUndefined(); - await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(NotImplementedHttpError); }); it('deletes the resource from the store and returns the correct response.', async(): Promise => { diff --git a/test/unit/ldp/operations/GetOperationHandler.test.ts b/test/unit/ldp/operations/GetOperationHandler.test.ts index f646766e9..17de59a2c 100644 --- a/test/unit/ldp/operations/GetOperationHandler.test.ts +++ b/test/unit/ldp/operations/GetOperationHandler.test.ts @@ -2,7 +2,7 @@ import { GetOperationHandler } from '../../../../src/ldp/operations/GetOperation import type { Operation } from '../../../../src/ldp/operations/Operation'; import type { Representation } from '../../../../src/ldp/representation/Representation'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A GetOperationHandler', (): void => { const store = { @@ -13,7 +13,7 @@ describe('A GetOperationHandler', (): void => { it('only supports GET operations.', async(): Promise => { await expect(handler.canHandle({ method: 'GET' } as Operation)).resolves.toBeUndefined(); - await expect(handler.canHandle({ method: 'POST' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle({ method: 'POST' } as Operation)).rejects.toThrow(NotImplementedHttpError); }); it('returns the representation from the store with the correct response.', async(): Promise => { diff --git a/test/unit/ldp/operations/HeadOperationHandler.test.ts b/test/unit/ldp/operations/HeadOperationHandler.test.ts index b5efd58aa..2bdb8e892 100644 --- a/test/unit/ldp/operations/HeadOperationHandler.test.ts +++ b/test/unit/ldp/operations/HeadOperationHandler.test.ts @@ -3,7 +3,7 @@ import { HeadOperationHandler } from '../../../../src/ldp/operations/HeadOperati import type { Operation } from '../../../../src/ldp/operations/Operation'; import type { Representation } from '../../../../src/ldp/representation/Representation'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A HeadOperationHandler', (): void => { let store: ResourceStore; @@ -21,8 +21,8 @@ describe('A HeadOperationHandler', (): void => { it('only supports HEAD operations.', async(): Promise => { await expect(handler.canHandle({ method: 'HEAD' } as Operation)).resolves.toBeUndefined(); - await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(UnsupportedHttpError); - await expect(handler.canHandle({ method: 'POST' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(NotImplementedHttpError); + await expect(handler.canHandle({ method: 'POST' } as Operation)).rejects.toThrow(NotImplementedHttpError); }); it('returns the representation from the store with the correct response.', async(): Promise => { diff --git a/test/unit/ldp/operations/PatchOperationHandler.test.ts b/test/unit/ldp/operations/PatchOperationHandler.test.ts index 2c66b752d..b1362845d 100644 --- a/test/unit/ldp/operations/PatchOperationHandler.test.ts +++ b/test/unit/ldp/operations/PatchOperationHandler.test.ts @@ -1,7 +1,7 @@ import type { Operation } from '../../../../src/ldp/operations/Operation'; import { PatchOperationHandler } from '../../../../src/ldp/operations/PatchOperationHandler'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A PatchOperationHandler', (): void => { const store = {} as unknown as ResourceStore; @@ -12,7 +12,7 @@ describe('A PatchOperationHandler', (): void => { it('only supports PATCH operations.', async(): Promise => { await expect(handler.canHandle({ method: 'PATCH' } as Operation)).resolves.toBeUndefined(); - await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(NotImplementedHttpError); }); it('deletes the resource from the store and returns the correct response.', async(): Promise => { diff --git a/test/unit/ldp/operations/PostOperationHandler.test.ts b/test/unit/ldp/operations/PostOperationHandler.test.ts index 811c5e38b..9f848ecd2 100644 --- a/test/unit/ldp/operations/PostOperationHandler.test.ts +++ b/test/unit/ldp/operations/PostOperationHandler.test.ts @@ -3,7 +3,8 @@ import { PostOperationHandler } from '../../../../src/ldp/operations/PostOperati import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../../../src/ldp/representation/ResourceIdentifier'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; import { HTTP } from '../../../../src/util/UriConstants'; describe('A PostOperationHandler', (): void => { @@ -16,11 +17,11 @@ describe('A PostOperationHandler', (): void => { await expect(handler.canHandle({ method: 'POST', body: { }} as Operation)) .resolves.toBeUndefined(); await expect(handler.canHandle({ method: 'GET', body: { }} as Operation)) - .rejects.toThrow(UnsupportedHttpError); + .rejects.toThrow(NotImplementedHttpError); }); it('errors if there is no body.', async(): Promise => { - await expect(handler.handle({ method: 'POST' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.handle({ method: 'POST' } as Operation)).rejects.toThrow(BadRequestHttpError); }); it('adds the given representation to the store and returns the correct response.', async(): Promise => { diff --git a/test/unit/ldp/operations/PutOperationHandler.test.ts b/test/unit/ldp/operations/PutOperationHandler.test.ts index 8bee0a4a2..b23af1960 100644 --- a/test/unit/ldp/operations/PutOperationHandler.test.ts +++ b/test/unit/ldp/operations/PutOperationHandler.test.ts @@ -1,7 +1,8 @@ import type { Operation } from '../../../../src/ldp/operations/Operation'; import { PutOperationHandler } from '../../../../src/ldp/operations/PutOperationHandler'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A PutOperationHandler', (): void => { const store = {} as unknown as ResourceStore; @@ -12,7 +13,7 @@ describe('A PutOperationHandler', (): void => { }); it('only supports PUT operations.', async(): Promise => { - await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(NotImplementedHttpError); await expect(handler.canHandle({ method: 'PUT' } as Operation)).resolves.toBeUndefined(); }); @@ -26,6 +27,6 @@ describe('A PutOperationHandler', (): void => { }); it('errors when there is no body.', async(): Promise => { - await expect(handler.handle({ method: 'PUT' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.handle({ method: 'PUT' } as Operation)).rejects.toThrow(BadRequestHttpError); }); }); diff --git a/test/unit/ldp/permissions/BasePermissionsExtractor.test.ts b/test/unit/ldp/permissions/BasePermissionsExtractor.test.ts index 7f4839f14..4475df98b 100644 --- a/test/unit/ldp/permissions/BasePermissionsExtractor.test.ts +++ b/test/unit/ldp/permissions/BasePermissionsExtractor.test.ts @@ -1,6 +1,6 @@ import type { Operation } from '../../../../src/ldp/operations/Operation'; import { MethodPermissionsExtractor } from '../../../../src/ldp/permissions/MethodPermissionsExtractor'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; describe('A MethodPermissionsExtractor', (): void => { const extractor = new MethodPermissionsExtractor(); @@ -11,7 +11,7 @@ describe('A MethodPermissionsExtractor', (): void => { await expect(extractor.canHandle({ method: 'POST' } as Operation)).resolves.toBeUndefined(); await expect(extractor.canHandle({ method: 'PUT' } as Operation)).resolves.toBeUndefined(); await expect(extractor.canHandle({ method: 'DELETE' } as Operation)).resolves.toBeUndefined(); - await expect(extractor.canHandle({ method: 'PATCH' } as Operation)).rejects.toThrow(UnsupportedHttpError); + await expect(extractor.canHandle({ method: 'PATCH' } as Operation)).rejects.toThrow(NotImplementedHttpError); }); it('requires read for HEAD operations.', async(): Promise => { diff --git a/test/unit/ldp/permissions/SparqlPatchPermissionsExtractor.test.ts b/test/unit/ldp/permissions/SparqlPatchPermissionsExtractor.test.ts index 4b677d7f9..d4f79bb41 100644 --- a/test/unit/ldp/permissions/SparqlPatchPermissionsExtractor.test.ts +++ b/test/unit/ldp/permissions/SparqlPatchPermissionsExtractor.test.ts @@ -2,7 +2,7 @@ import { Factory } from 'sparqlalgebrajs'; import type { SparqlUpdatePatch } from '../../../../src/ldp/http/SparqlUpdatePatch'; import type { Operation } from '../../../../src/ldp/operations/Operation'; import { SparqlPatchPermissionsExtractor } from '../../../../src/ldp/permissions/SparqlPatchPermissionsExtractor'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; describe('A SparqlPatchPermissionsExtractor', (): void => { const extractor = new SparqlPatchPermissionsExtractor(); @@ -12,14 +12,14 @@ describe('A SparqlPatchPermissionsExtractor', (): void => { const operation = { method: 'PATCH', body: { algebra: factory.createDeleteInsert() }} as unknown as Operation; await expect(extractor.canHandle(operation)).resolves.toBeUndefined(); await expect(extractor.canHandle({ ...operation, method: 'GET' })) - .rejects.toThrow(new UnsupportedHttpError('Cannot determine permissions of GET, only PATCH.')); + .rejects.toThrow(new BadRequestHttpError('Cannot determine permissions of GET, only PATCH.')); await expect(extractor.canHandle({ ...operation, body: undefined })) - .rejects.toThrow(new UnsupportedHttpError('Cannot determine permissions of PATCH operations without a body.')); + .rejects.toThrow(new BadRequestHttpError('Cannot determine permissions of PATCH operations without a body.')); await expect(extractor.canHandle({ ...operation, body: {} as SparqlUpdatePatch })) - .rejects.toThrow(new UnsupportedHttpError('Cannot determine permissions of non-SPARQL patches.')); + .rejects.toThrow(new BadRequestHttpError('Cannot determine permissions of non-SPARQL patches.')); await expect(extractor.canHandle({ ...operation, body: { algebra: factory.createMove('DEFAULT', 'DEFAULT') } as unknown as SparqlUpdatePatch })) - .rejects.toThrow(new UnsupportedHttpError('Cannot determine permissions of a PATCH without DELETE/INSERT.')); + .rejects.toThrow(new BadRequestHttpError('Cannot determine permissions of a PATCH without DELETE/INSERT.')); }); it('requires append for INSERT operations.', async(): Promise => { diff --git a/test/unit/storage/DataAccessorBasedStore.test.ts b/test/unit/storage/DataAccessorBasedStore.test.ts index ba36f0f8f..905be3281 100644 --- a/test/unit/storage/DataAccessorBasedStore.test.ts +++ b/test/unit/storage/DataAccessorBasedStore.test.ts @@ -7,11 +7,11 @@ import type { ResourceIdentifier } from '../../../src/ldp/representation/Resourc import type { DataAccessor } from '../../../src/storage/accessors/DataAccessor'; import { DataAccessorBasedStore } from '../../../src/storage/DataAccessorBasedStore'; import { INTERNAL_QUADS } from '../../../src/util/ContentTypes'; +import { BadRequestHttpError } from '../../../src/util/errors/BadRequestHttpError'; import { ConflictHttpError } from '../../../src/util/errors/ConflictHttpError'; import { MethodNotAllowedHttpError } from '../../../src/util/errors/MethodNotAllowedHttpError'; import { NotFoundHttpError } from '../../../src/util/errors/NotFoundHttpError'; -import { NotImplementedError } from '../../../src/util/errors/NotImplementedError'; -import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../src/util/errors/NotImplementedHttpError'; import type { Guarded } from '../../../src/util/GuardedStream'; import * as quadUtil from '../../../src/util/QuadUtil'; import { guardedStreamFrom } from '../../../src/util/StreamUtil'; @@ -29,7 +29,7 @@ class SimpleDataAccessor implements DataAccessor { public async canHandle(representation: Representation): Promise { if (!representation.binary) { - throw new UnsupportedHttpError(); + throw new BadRequestHttpError(); } } @@ -124,7 +124,7 @@ describe('A DataAccessorBasedStore', (): void => { it('checks if the DataAccessor supports the data.', async(): Promise => { const resourceID = { path: `${root}container/` }; representation.binary = false; - await expect(store.addResource(resourceID, representation)).rejects.toThrow(UnsupportedHttpError); + await expect(store.addResource(resourceID, representation)).rejects.toThrow(BadRequestHttpError); }); it('will 404 if the target does not exist and does not end in a slash.', async(): Promise => { @@ -150,7 +150,7 @@ describe('A DataAccessorBasedStore', (): void => { it('errors when trying to create a container with non-RDF data.', async(): Promise => { const resourceID = { path: root }; representation.metadata.add(RDF.type, toNamedNode(LDP.Container)); - await expect(store.addResource(resourceID, representation)).rejects.toThrow(UnsupportedHttpError); + await expect(store.addResource(resourceID, representation)).rejects.toThrow(BadRequestHttpError); }); it('passes the result along if the MetadataController throws a non-Error.', async(): Promise => { @@ -241,7 +241,7 @@ describe('A DataAccessorBasedStore', (): void => { it('checks if the DataAccessor supports the data.', async(): Promise => { const resourceID = { path: `${root}container/` }; representation.binary = false; - await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow(UnsupportedHttpError); + await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow(BadRequestHttpError); }); it('will error if the path has a different slash than the existing one.', async(): Promise => { @@ -266,14 +266,14 @@ describe('A DataAccessorBasedStore', (): void => { it('will error if the ending slash does not match its resource type.', async(): Promise => { const resourceID = { path: `${root}resource/` }; await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow( - new UnsupportedHttpError('Containers should have a `/` at the end of their path, resources should not.'), + new BadRequestHttpError('Containers should have a `/` at the end of their path, resources should not.'), ); }); it('errors when trying to create a container with non-RDF data.', async(): Promise => { const resourceID = { path: `${root}container/` }; representation.metadata.add(RDF.type, toNamedNode(LDP.Container)); - await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow(UnsupportedHttpError); + await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow(BadRequestHttpError); }); it('can write resources.', async(): Promise => { @@ -328,7 +328,7 @@ describe('A DataAccessorBasedStore', (): void => { describe('modifying a Representation', (): void => { it('is not supported.', async(): Promise => { await expect(store.modifyResource()) - .rejects.toThrow(new NotImplementedError('Patches are not supported by the default store.')); + .rejects.toThrow(new NotImplementedHttpError('Patches are not supported by the default store.')); }); }); diff --git a/test/unit/storage/RoutingResourceStore.test.ts b/test/unit/storage/RoutingResourceStore.test.ts index c0f0104b3..4051f7e15 100644 --- a/test/unit/storage/RoutingResourceStore.test.ts +++ b/test/unit/storage/RoutingResourceStore.test.ts @@ -1,7 +1,7 @@ import type { ResourceStore } from '../../../src/storage/ResourceStore'; import { RoutingResourceStore } from '../../../src/storage/RoutingResourceStore'; import { NotFoundHttpError } from '../../../src/util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../src/util/errors/NotImplementedHttpError'; import { StaticAsyncHandler } from '../../util/StaticAsyncHandler'; describe('A RoutingResourceStore', (): void => { @@ -61,7 +61,7 @@ describe('A RoutingResourceStore', (): void => { it('throws a 404 if there is no body and no store was found.', async(): Promise => { rule.canHandle = (): any => { - throw new UnsupportedHttpError(); + throw new NotImplementedHttpError(); }; await expect(store.getRepresentation(identifier, 'preferences' as any, 'conditions' as any)) .rejects.toThrow(NotFoundHttpError); diff --git a/test/unit/storage/accessors/SparqlDataAccessor.test.ts b/test/unit/storage/accessors/SparqlDataAccessor.test.ts index d43e4c978..f42f7de37 100644 --- a/test/unit/storage/accessors/SparqlDataAccessor.test.ts +++ b/test/unit/storage/accessors/SparqlDataAccessor.test.ts @@ -6,9 +6,9 @@ import type { Quad } from 'rdf-js'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { SparqlDataAccessor } from '../../../../src/storage/accessors/SparqlDataAccessor'; import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { ConflictHttpError } from '../../../../src/util/errors/ConflictHttpError'; import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; import { UnsupportedMediaTypeHttpError } from '../../../../src/util/errors/UnsupportedMediaTypeHttpError'; import type { Guarded } from '../../../../src/util/GuardedStream'; import { guardedStreamFrom } from '../../../../src/util/StreamUtil'; @@ -214,7 +214,7 @@ describe('A SparqlDataAccessor', (): void => { [ quad(namedNode('http://name'), namedNode('http://pred'), literal('value'), namedNode('badGraph!')) ], ); await expect(accessor.writeDocument({ path: 'http://test.com/container/resource' }, data, metadata)) - .rejects.toThrow(new UnsupportedHttpError('Only triples in the default graph are supported.')); + .rejects.toThrow(new BadRequestHttpError('Only triples in the default graph are supported.')); }); it('errors when the SPARQL endpoint fails during reading.', async(): Promise => { diff --git a/test/unit/storage/conversion/ConversionUtil.test.ts b/test/unit/storage/conversion/ConversionUtil.test.ts index a2ec17ee5..5a4d3746a 100644 --- a/test/unit/storage/conversion/ConversionUtil.test.ts +++ b/test/unit/storage/conversion/ConversionUtil.test.ts @@ -7,8 +7,8 @@ import { matchingTypes, validateRequestArgs, } from '../../../../src/storage/conversion/ConversionUtil'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { InternalServerError } from '../../../../src/util/errors/InternalServerError'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; describe('ConversionUtil', (): void => { const identifier: ResourceIdentifier = { path: 'path' }; @@ -66,7 +66,7 @@ describe('ConversionUtil', (): void => { const preferences: RepresentationPreferences = { type: [{ value: 'b/x', weight: 1 }, { value: 'b/x', weight: 0 }]}; expect((): any => matchingTypes(preferences, [ 'b/x' ])) - .toThrow(new UnsupportedHttpError(`Duplicate type preference found: b/x`)); + .toThrow(new BadRequestHttpError(`Duplicate type preference found: b/x`)); }); it('errors if there invalid types.', async(): Promise => { diff --git a/test/unit/storage/conversion/RdfToQuadConverter.test.ts b/test/unit/storage/conversion/RdfToQuadConverter.test.ts index 6cd26befa..7c8b8b351 100644 --- a/test/unit/storage/conversion/RdfToQuadConverter.test.ts +++ b/test/unit/storage/conversion/RdfToQuadConverter.test.ts @@ -9,7 +9,7 @@ import type { RepresentationPreferences } from '../../../../src/ldp/representati import type { ResourceIdentifier } from '../../../../src/ldp/representation/ResourceIdentifier'; import { RdfToQuadConverter } from '../../../../src/storage/conversion/RdfToQuadConverter'; import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { CONTENT_TYPE } from '../../../../src/util/UriConstants'; describe('A RdfToQuadConverter.test.ts', (): void => { @@ -80,7 +80,7 @@ describe('A RdfToQuadConverter.test.ts', (): void => { ) ]); }); - it('throws an UnsupportedHttpError on invalid triple data.', async(): Promise => { + it('throws an BadRequestHttpError on invalid triple data.', async(): Promise => { const metadata = new RepresentationMetadata({ [CONTENT_TYPE]: 'text/turtle' }); const representation = { data: streamifyArray([ ' { metadata: expect.any(RepresentationMetadata), }); expect(result.metadata.contentType).toEqual(INTERNAL_QUADS); - await expect(arrayifyStream(result.data)).rejects.toThrow(UnsupportedHttpError); + await expect(arrayifyStream(result.data)).rejects.toThrow(BadRequestHttpError); }); }); diff --git a/test/unit/storage/mapping/ExtensionBasedMapper.test.ts b/test/unit/storage/mapping/ExtensionBasedMapper.test.ts index f356c4add..9e3ddaceb 100644 --- a/test/unit/storage/mapping/ExtensionBasedMapper.test.ts +++ b/test/unit/storage/mapping/ExtensionBasedMapper.test.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import { ExtensionBasedMapper } from '../../../../src/storage/mapping/ExtensionBasedMapper'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; import { trimTrailingSlashes } from '../../../../src/util/PathUtil'; jest.mock('fs'); @@ -27,12 +27,12 @@ describe('An ExtensionBasedMapper', (): void => { it('throws 404 if the relative path does not start with a slash.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${trimTrailingSlashes(base)}test` })) - .rejects.toThrow(new UnsupportedHttpError('URL needs a / after the base')); + .rejects.toThrow(new BadRequestHttpError('URL needs a / after the base')); }); it('throws 400 if the input path contains relative parts.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${base}test/../test2` })) - .rejects.toThrow(new UnsupportedHttpError('Disallowed /.. segment in URL')); + .rejects.toThrow(new BadRequestHttpError('Disallowed /.. segment in URL')); }); it('returns the corresponding file path for container identifiers.', async(): Promise => { @@ -44,7 +44,7 @@ describe('An ExtensionBasedMapper', (): void => { it('rejects URLs that end with "$.{extension}".', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${base}test$.txt` })) - .rejects.toThrow(new UnsupportedHttpError('Identifiers cannot contain a dollar sign before their extension')); + .rejects.toThrow(new BadRequestHttpError('Identifiers cannot contain a dollar sign before their extension')); }); it('throws 404 when looking in a folder that does not exist.', async(): Promise => { @@ -95,7 +95,7 @@ describe('An ExtensionBasedMapper', (): void => { it('throws 400 if the given content-type is not recognized.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${base}test.txt` }, 'fake/data')) - .rejects.toThrow(new UnsupportedHttpError(`Unsupported content type fake/data`)); + .rejects.toThrow(new BadRequestHttpError(`Unsupported content type fake/data`)); }); }); diff --git a/test/unit/storage/mapping/FixedContentTypeMapper.test.ts b/test/unit/storage/mapping/FixedContentTypeMapper.test.ts index f7894cbfb..89d0e209d 100644 --- a/test/unit/storage/mapping/FixedContentTypeMapper.test.ts +++ b/test/unit/storage/mapping/FixedContentTypeMapper.test.ts @@ -1,6 +1,6 @@ import { FixedContentTypeMapper } from '../../../../src/storage/mapping/FixedContentTypeMapper'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; import { trimTrailingSlashes } from '../../../../src/util/PathUtil'; jest.mock('fs'); @@ -17,12 +17,12 @@ describe('An FixedContentTypeMapper', (): void => { it('throws 404 if the relative path does not start with a slash.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${trimTrailingSlashes(base)}test` })) - .rejects.toThrow(new UnsupportedHttpError('URL needs a / after the base')); + .rejects.toThrow(new BadRequestHttpError('URL needs a / after the base')); }); it('throws 400 if the input path contains relative parts.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${base}test/../test2` })) - .rejects.toThrow(new UnsupportedHttpError('Disallowed /.. segment in URL')); + .rejects.toThrow(new BadRequestHttpError('Disallowed /.. segment in URL')); }); it('returns the corresponding file path for container identifiers.', async(): Promise => { @@ -60,7 +60,7 @@ describe('An FixedContentTypeMapper', (): void => { it('throws 400 if the given content-type is not supported.', async(): Promise => { await expect(mapper.mapUrlToFilePath({ path: `${base}test.ttl` }, 'application/n-quads')).rejects - .toThrow(new UnsupportedHttpError(`Unsupported content type application/n-quads, only text/turtle is allowed`)); + .toThrow(new BadRequestHttpError(`Unsupported content type application/n-quads, only text/turtle is allowed`)); }); }); diff --git a/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts b/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts index 42b4bb397..20bb3ecab 100644 --- a/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts +++ b/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts @@ -8,7 +8,7 @@ import { RepresentationMetadata } from '../../../../src/ldp/representation/Repre import { SparqlUpdatePatchHandler } from '../../../../src/storage/patch/SparqlUpdatePatchHandler'; import type { ResourceStore } from '../../../../src/storage/ResourceStore'; import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; import type { Lock } from '../../../../src/util/locking/Lock'; import type { ResourceLocker } from '../../../../src/util/locking/ResourceLocker'; @@ -86,7 +86,7 @@ describe('A SparqlUpdatePatchHandler', (): void => { patch: { algebra: {}} as SparqlUpdatePatch }; await expect(handler.canHandle(input)).resolves.toBeUndefined(); delete (input.patch as any).algebra; - await expect(handler.canHandle(input)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle(input)).rejects.toThrow(NotImplementedHttpError); }); it('handles INSERT DATA updates.', async(): Promise => { diff --git a/test/unit/storage/routing/PreferenceSupport.test.ts b/test/unit/storage/routing/PreferenceSupport.test.ts index 4a8ecb3ee..95b0d37cd 100644 --- a/test/unit/storage/routing/PreferenceSupport.test.ts +++ b/test/unit/storage/routing/PreferenceSupport.test.ts @@ -3,7 +3,7 @@ import type { RepresentationPreferences } from '../../../../src/ldp/representati import type { ResourceIdentifier } from '../../../../src/ldp/representation/ResourceIdentifier'; import type { RepresentationConverter } from '../../../../src/storage/conversion/RepresentationConverter'; import { PreferenceSupport } from '../../../../src/storage/routing/PreferenceSupport'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; describe('A PreferenceSupport', (): void => { const type = 'internal/quads'; @@ -26,7 +26,7 @@ describe('A PreferenceSupport', (): void => { it('returns false if the converter does not support the input.', async(): Promise => { converter.canHandle = jest.fn((): any => { - throw new UnsupportedHttpError(); + throw new BadRequestHttpError(); }); await expect(support.supports({ identifier, representation })).resolves.toBe(false); expect(converter.canHandle).toHaveBeenCalledTimes(1); diff --git a/test/unit/storage/routing/RegexRouterRule.test.ts b/test/unit/storage/routing/RegexRouterRule.test.ts index fa611c2ac..c9a4d62d5 100644 --- a/test/unit/storage/routing/RegexRouterRule.test.ts +++ b/test/unit/storage/routing/RegexRouterRule.test.ts @@ -1,6 +1,6 @@ import type { ResourceStore } from '../../../../src/storage/ResourceStore'; import { RegexRouterRule } from '../../../../src/storage/routing/RegexRouterRule'; -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; describe('A RegexRouterRule', (): void => { const base = 'http://test.com/'; @@ -9,13 +9,13 @@ describe('A RegexRouterRule', (): void => { it('rejects identifiers not containing the base.', async(): Promise => { const router = new RegexRouterRule(base, {}); await expect(router.canHandle({ identifier: { path: 'http://notTest.com/apple' }})) - .rejects.toThrow(new UnsupportedHttpError(`Identifiers need to start with http://test.com`)); + .rejects.toThrow(new BadRequestHttpError(`Identifiers need to start with http://test.com`)); }); it('rejects identifiers not matching any regex.', async(): Promise => { const router = new RegexRouterRule(base, { pear: store }); await expect(router.canHandle({ identifier: { path: `${base}apple/` }})) - .rejects.toThrow(new UnsupportedHttpError(`No stored regexes match http://test.com/apple/`)); + .rejects.toThrow(new BadRequestHttpError(`No stored regexes match http://test.com/apple/`)); }); it('accepts identifiers matching any regex.', async(): Promise => { diff --git a/test/unit/util/FirstCompositeHandler.test.ts b/test/unit/util/FirstCompositeHandler.test.ts index 79df5249b..87605fd2d 100644 --- a/test/unit/util/FirstCompositeHandler.test.ts +++ b/test/unit/util/FirstCompositeHandler.test.ts @@ -1,6 +1,6 @@ import type { AsyncHandler } from '../../../src/util/AsyncHandler'; +import { BadRequestHttpError } from '../../../src/util/errors/BadRequestHttpError'; import { HttpError } from '../../../src/util/errors/HttpError'; -import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError'; import { FirstCompositeHandler } from '../../../src/util/FirstCompositeHandler'; import { StaticAsyncHandler } from '../../util/StaticAsyncHandler'; @@ -111,7 +111,7 @@ describe('A FirstCompositeHandler', (): void => { }); }); - it('throws an UnsupportedHttpError if handlers throw different errors.', async(): Promise => { + it('throws an BadRequestHttpError if handlers throw different errors.', async(): Promise => { handlerTrue.canHandle = async(): Promise => { throw new HttpError(401, 'UnauthorizedHttpError'); }; @@ -120,7 +120,7 @@ describe('A FirstCompositeHandler', (): void => { }; const handler = new FirstCompositeHandler([ handlerTrue, handlerFalse ]); - await expect(handler.canHandle(null)).rejects.toThrow(UnsupportedHttpError); + await expect(handler.canHandle(null)).rejects.toThrow(BadRequestHttpError); }); }); }); diff --git a/test/unit/util/errors/UnsupportedHttpError.test.ts b/test/unit/util/errors/BadRequestHttpError.test.ts similarity index 53% rename from test/unit/util/errors/UnsupportedHttpError.test.ts rename to test/unit/util/errors/BadRequestHttpError.test.ts index 63261628d..76b95227e 100644 --- a/test/unit/util/errors/UnsupportedHttpError.test.ts +++ b/test/unit/util/errors/BadRequestHttpError.test.ts @@ -1,16 +1,16 @@ -import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; +import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; -describe('An UnsupportedHttpError', (): void => { +describe('An BadRequestHttpError', (): void => { it('has status code 400.', async(): Promise => { - const error = new UnsupportedHttpError('test'); + const error = new BadRequestHttpError('test'); expect(error.statusCode).toEqual(400); expect(error.message).toEqual('test'); - expect(error.name).toEqual('UnsupportedHttpError'); + expect(error.name).toEqual('BadRequestHttpError'); }); it('has a default message if none was provided.', async(): Promise => { - const error = new UnsupportedHttpError(); + const error = new BadRequestHttpError(); expect(error.message).toEqual('The given input is not supported by the server configuration.'); });