From 4dec6771ecc7abe20bb2d453517e44898bf575ea Mon Sep 17 00:00:00 2001 From: frcroth Date: Mon, 6 Nov 2023 11:41:44 +0100 Subject: [PATCH 1/3] Handle http unknown host exception --- .../scala/com/scalableminds/util/tools/Fox.scala | 13 +++++++++++++ .../datastore/datavault/HttpsDataVault.scala | 9 +++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/util/src/main/scala/com/scalableminds/util/tools/Fox.scala b/util/src/main/scala/com/scalableminds/util/tools/Fox.scala index c832423bfc3..9f9fd540e4a 100644 --- a/util/src/main/scala/com/scalableminds/util/tools/Fox.scala +++ b/util/src/main/scala/com/scalableminds/util/tools/Fox.scala @@ -242,6 +242,19 @@ object Fox extends FoxImplicits { failure.msg + formatStackTrace(failure) + formatChain(failure.chain) } + + /** + * Transforms a Future[T] into a Fox[T] where the Future is transformed into a Fox with a Failure if the Future fails. + * Useful for Futures containing exceptions. + */ + def transformFuture[T](future: Future[T])(implicit ec: ExecutionContext): Fox[T] = + for { + fut <- future.transform { + case Success(value) => Try(Fox.successful(value)) + case scala.util.Failure(e) => Try(Fox.failure(e.getMessage, Full(e))) + } + f <- fut + } yield f } class Fox[+A](val futureBox: Future[Box[A]])(implicit ec: ExecutionContext) { diff --git a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/datavault/HttpsDataVault.scala b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/datavault/HttpsDataVault.scala index db769dd342e..9ef1bf7871e 100644 --- a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/datavault/HttpsDataVault.scala +++ b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/datavault/HttpsDataVault.scala @@ -50,7 +50,7 @@ class HttpsDataVault(credential: Option[DataVaultCredential], ws: WSClient) exte headerInfoCache.getOrLoad( uri, { uri => for { - response <- ws.url(uri.toString).withRequestTimeout(readTimeout).head() + response <- Fox.transformFuture(ws.url(uri.toString).withRequestTimeout(readTimeout).head()) acceptsPartialRequests = response.headerValues("Accept-Ranges").contains("bytes") dataSize = response.header("Content-Length").map(_.toLong).getOrElse(0L) } yield (acceptsPartialRequests, dataSize) @@ -60,19 +60,20 @@ class HttpsDataVault(credential: Option[DataVaultCredential], ws: WSClient) exte private def getWithRange(uri: URI, range: NumericRange[Long])(implicit ec: ExecutionContext): Fox[WSResponse] = for { _ <- ensureRangeRequestsSupported(uri) - response <- buildRequest(uri).withHttpHeaders("Range" -> s"bytes=${range.start}-${range.end - 1}").get() + response <- Fox.transformFuture( + buildRequest(uri).withHttpHeaders("Range" -> s"bytes=${range.start}-${range.end - 1}").get()) _ = updateRangeRequestsSupportedForResponse(response) } yield response private def getWithSuffixRange(uri: URI, length: Long)(implicit ec: ExecutionContext): Fox[WSResponse] = for { _ <- ensureRangeRequestsSupported(uri) - response <- buildRequest(uri).withHttpHeaders("Range" -> s"bytes=-$length").get() + response <- Fox.transformFuture(buildRequest(uri).withHttpHeaders("Range" -> s"bytes=-$length").get()) _ = updateRangeRequestsSupportedForResponse(response) } yield response private def getComplete(uri: URI)(implicit ec: ExecutionContext): Fox[WSResponse] = - buildRequest(uri).get() + Fox.transformFuture(buildRequest(uri).get()) private def ensureRangeRequestsSupported(uri: URI)(implicit ec: ExecutionContext): Fox[Unit] = for { From 26fba19168df6e36c8e61f6185cedfd0c1a89785 Mon Sep 17 00:00:00 2001 From: frcroth Date: Mon, 6 Nov 2023 11:43:31 +0100 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 0dfeedfed29..71e78115837 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -19,6 +19,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - Searching the segments in the sidebar will highlight newly focused segments properly now. [#7406](https://github.com/scalableminds/webknossos/pull/7406) - Fixed a bug when opening a task for which a mag restriction exists. The bug only occurred when the referenced mag didn't exist in the dataset. [#7403](https://github.com/scalableminds/webknossos/pull/7403) - Fixed styling issues with the maintenance banner so that it no longer overlaps other menus, tabs, and buttons. [#7421](https://github.com/scalableminds/webknossos/pull/7421) +- Exploring HTTP uris of unknown hosts no longer causes an exception error message to be displayed. [#7422](https://github.com/scalableminds/webknossos/pull/7422) ### Removed From 6b6904969713e4067e259a0afda57b3cb4f7d8b3 Mon Sep 17 00:00:00 2001 From: Florian M Date: Mon, 6 Nov 2023 13:14:34 +0100 Subject: [PATCH 3/3] change wording in comment --- util/src/main/scala/com/scalableminds/util/tools/Fox.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/util/src/main/scala/com/scalableminds/util/tools/Fox.scala b/util/src/main/scala/com/scalableminds/util/tools/Fox.scala index 9f9fd540e4a..a92a8a9a100 100644 --- a/util/src/main/scala/com/scalableminds/util/tools/Fox.scala +++ b/util/src/main/scala/com/scalableminds/util/tools/Fox.scala @@ -244,8 +244,7 @@ object Fox extends FoxImplicits { } /** - * Transforms a Future[T] into a Fox[T] where the Future is transformed into a Fox with a Failure if the Future fails. - * Useful for Futures containing exceptions. + * Transform a Future[T] into a Fox[T] such that if the Future contains an exception, it is turned into a Fox.failure */ def transformFuture[T](future: Future[T])(implicit ec: ExecutionContext): Fox[T] = for {