From 33e03e68f3b4afa04017bc5ca014c5f5fde6c49f Mon Sep 17 00:00:00 2001 From: navibyte <88932567+navispatial@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:00:31 +0300 Subject: [PATCH] feat(geodata): Map HTTP status codes to feature service exception (OGC API Features) #68 --- dart/geodata/CHANGELOG.md | 1 + .../src/core/features/feature_failure.dart | 83 ++++++++++++++++++- .../lib/src/utils/feature_http_adapter.dart | 20 +++++ 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/dart/geodata/CHANGELOG.md b/dart/geodata/CHANGELOG.md index 9300cf24..ee5fd03d 100644 --- a/dart/geodata/CHANGELOG.md +++ b/dart/geodata/CHANGELOG.md @@ -9,6 +9,7 @@ NOTE: Version 0.12.0 currently [under development](https://github.com/navibyte/g 🧩 Features: * [Full client-side support for calling OGC API Features service according to Part 1 + 2 #9](https://github.com/navibyte/geospatial/issues/9) * [Add support for API definition (like Open API 3.0) when accessing OGC API Features clients #170](https://github.com/navibyte/geospatial/issues/170) +* [Map HTTP status codes to feature service exception (OGC API Features) #68](https://github.com/navibyte/geospatial/issues/68) 🛠 Maintenance: * Removed extra internal export files and made internal imports more excplicit. diff --git a/dart/geodata/lib/src/core/features/feature_failure.dart b/dart/geodata/lib/src/core/features/feature_failure.dart index 990ce380..087c2089 100644 --- a/dart/geodata/lib/src/core/features/feature_failure.dart +++ b/dart/geodata/lib/src/core/features/feature_failure.dart @@ -9,12 +9,87 @@ enum FeatureFailure { /// An error occurred on the client side. clientError, - /// A service returned `Bad request` (ie. HTTP 400) for a query. + /// A query failed for undefined reasons. + queryFailed, + + /// A service returned `Found` (ie. HTTP 302) for a query. + /// + /// OGC API Common: "The target resource was found but resides temporarily + /// under a different URI. A 302 response is not evidence that the operation + /// has been successfully completed." + found, + + /// A service returned `See Other` (ie. HTTP 303) for a query. + /// + /// OGC API Common: "The server is redirecting the user agent to a different + /// resource. A 303 response is not evidence that the operation has been + /// successfully completed."" + seeOther, + + /// A service returned `Not Modified` (ie. HTTP 304) for a query. + /// + /// OGC API Common: "An entity tag was provided in the request and the + /// resource has not changed since the previous request." + notModified, + + /// A service returned `Temporary Redirect` (ie. HTTP 307) for a query. + /// + /// OGC API Common: "The target resource resides temporarily under a different + /// URI and the user agent MUST NOT change the request method if it performs + /// an automatic redirection to that URI." + temporaryRedirect, + + /// A service returned `Permanent Redirect` (ie. HTTP 308) for a query. + /// + /// OGC API Common: "Indicates that the target resource has been assigned a + /// new permanent URI and any future references to this resource ought to use + /// one of the enclosed URIs." + permanentRedirect, + + /// A service returned `Bad Request` (ie. HTTP 400) for a query. + /// + /// OGC API Common: The server cannot or will not process the request due to + /// an apparent client error. For example, a query parameter had an incorrect + /// value." badRequest, - /// A service returned `Not found` (ie. HTTP 404) for a query. + /// A service returned `Unauthorized` (ie. HTTP 401) for a query. + /// + /// OGC API Common: "The request requires user authentication. The response + /// includes a WWW-Authenticate header field containing a challenge applicable + /// to the requested resource." + unauthorized, + + /// A service returned `Forbidden` (ie. HTTP 403) for a query. + /// + /// OGC API Common: "The server understood the request, but is refusing to + /// fulfill it. While status code 401 indicates missing or bad authentication, + /// status code 403 indicates that authentication is not the issue, but the + /// client is not authorized to perform the requested operation on the + /// resource." + forbidden, + + /// A service returned `Not Found` (ie. HTTP 404) for a query. + /// + /// OGC API Common: "The requested resource does not exist on the server. For + /// example, a path parameter had an incorrect value." notFound, - /// A query failed for undefined reasons. - queryFailed, + /// A service returned `Method Not Allowed` (ie. HTTP 405) for a query. + /// + /// OGC API Common "The request method is not supported. For example, a POST + /// request was submitted, but the resource only supports GET requests." + methodNotAllowed, + + /// A service returned `Not Acceptable` (ie. HTTP 406) for a query. + /// + /// OGC API Common: "Content negotiation failed. For example, the Accept + /// header submitted in the request did not support any of the media types + /// supported by the server for the requested resource." + notAcceptable, + + /// A service returned `Internal Server Error` (ie. HTTP 500) for a query. + /// + /// OGC API Common: "An internal error occurred in the server." + internalServerError, } diff --git a/dart/geodata/lib/src/utils/feature_http_adapter.dart b/dart/geodata/lib/src/utils/feature_http_adapter.dart index be8f1cd2..5a0becae 100644 --- a/dart/geodata/lib/src/utils/feature_http_adapter.dart +++ b/dart/geodata/lib/src/utils/feature_http_adapter.dart @@ -106,10 +106,30 @@ class FeatureHttpAdapter { // map JSON data to an entity return toEntity(data, response.headers); + case 302: + throw const ServiceException(FeatureFailure.found); + case 303: + throw const ServiceException(FeatureFailure.seeOther); + case 304: + throw const ServiceException(FeatureFailure.notModified); + case 307: + throw const ServiceException(FeatureFailure.temporaryRedirect); + case 308: + throw const ServiceException(FeatureFailure.permanentRedirect); case 400: throw const ServiceException(FeatureFailure.badRequest); + case 401: + throw const ServiceException(FeatureFailure.unauthorized); + case 403: + throw const ServiceException(FeatureFailure.forbidden); case 404: throw const ServiceException(FeatureFailure.notFound); + case 405: + throw const ServiceException(FeatureFailure.methodNotAllowed); + case 406: + throw const ServiceException(FeatureFailure.notAcceptable); + case 500: + throw const ServiceException(FeatureFailure.internalServerError); default: throw const ServiceException(FeatureFailure.queryFailed); }