From b2d7ed88e48ca61305450c85dcf4462839b88f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 9 Dec 2021 15:48:42 +0100 Subject: [PATCH] Explain provision exception (#1890) When the ResourceLinks class could not access the scmPathInfoStore due to an invalid request scope (that is outside http requests), this might lead to confusion due to messages from guice. We try to "fix" these by using an own explanation to what probably went wrong and how to mitigate this. --- .../resources/OutOfRequestScopeException.java | 44 +++++++ .../scm/api/v2/resources/ResourceLinks.java | 112 ++++++++++-------- 2 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/OutOfRequestScopeException.java diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/OutOfRequestScopeException.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/OutOfRequestScopeException.java new file mode 100644 index 0000000000..db7ece1456 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/OutOfRequestScopeException.java @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.api.v2.resources; + +import com.google.inject.ProvisionException; + +public class OutOfRequestScopeException extends RuntimeException { + + public OutOfRequestScopeException(ProvisionException cause) { + super("Out of request scope\n\n" + + "==============================================================\n" + + "Cannot create links, because we are out of the request scope.\n" + + "Most probably this is because you were trying to create a link\n" + + "in a context that has no encapsulating http request. It is not\n" + + "possible to create these links outside of requests, because\n" + + "the computation uses the originating url of the http request\n" + + "as a basis. To create urls outside of request scopes, please\n" + + "inject an instance of ScmConfiguration and use getBaseUrl().\n" + + "==============================================================\n", + cause); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java index 743800c2a1..d7e5315e10 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java @@ -24,6 +24,8 @@ package sonia.scm.api.v2.resources; +import com.google.inject.OutOfScopeException; +import com.google.inject.ProvisionException; import sonia.scm.security.gpg.UserPublicKeyResource; import javax.inject.Inject; @@ -51,8 +53,20 @@ class ResourceLinks { } } + private ScmPathInfoStore accessScmPathInfoStore() { + try { + return scmPathInfoStore.get(); + } catch (ProvisionException e) { + + if (e.getCause() instanceof OutOfScopeException) { + throw new OutOfRequestScopeException(e); + } + throw e; + } + } + GroupLinks group() { - return new GroupLinks(scmPathInfoStore.get().get()); + return new GroupLinks(accessScmPathInfoStore().get()); } static class GroupLinks { @@ -76,7 +90,7 @@ class ResourceLinks { } GroupCollectionLinks groupCollection() { - return new GroupCollectionLinks(scmPathInfoStore.get().get()); + return new GroupCollectionLinks(accessScmPathInfoStore().get()); } static class GroupCollectionLinks { @@ -96,7 +110,7 @@ class ResourceLinks { } UserLinks user() { - return new UserLinks(scmPathInfoStore.get().get()); + return new UserLinks(accessScmPathInfoStore().get()); } static class UserLinks { @@ -150,7 +164,7 @@ class ResourceLinks { } UserPermissionLinks userPermissions() { - return new UserPermissionLinks(scmPathInfoStore.get().get()); + return new UserPermissionLinks(accessScmPathInfoStore().get()); } static class UserPermissionLinks implements WithPermissionLinks { @@ -170,7 +184,7 @@ class ResourceLinks { } GroupPermissionLinks groupPermissions() { - return new GroupPermissionLinks(scmPathInfoStore.get().get()); + return new GroupPermissionLinks(accessScmPathInfoStore().get()); } static class GroupPermissionLinks implements WithPermissionLinks { @@ -190,7 +204,7 @@ class ResourceLinks { } MeLinks me() { - return new MeLinks(scmPathInfoStore.get().get(), this.user()); + return new MeLinks(accessScmPathInfoStore().get(), this.user()); } static class MeLinks { @@ -226,7 +240,7 @@ class ResourceLinks { } public ApiKeyCollectionLinks apiKeyCollection() { - return new ApiKeyCollectionLinks(scmPathInfoStore.get().get()); + return new ApiKeyCollectionLinks(accessScmPathInfoStore().get()); } static class ApiKeyCollectionLinks { @@ -246,7 +260,7 @@ class ResourceLinks { } public ApiKeyLinks apiKey() { - return new ApiKeyLinks(scmPathInfoStore.get().get()); + return new ApiKeyLinks(accessScmPathInfoStore().get()); } static class ApiKeyLinks { @@ -266,7 +280,7 @@ class ResourceLinks { } UserCollectionLinks userCollection() { - return new UserCollectionLinks(scmPathInfoStore.get().get()); + return new UserCollectionLinks(accessScmPathInfoStore().get()); } static class UserCollectionLinks { @@ -286,7 +300,7 @@ class ResourceLinks { } AutoCompleteLinks autoComplete() { - return new AutoCompleteLinks(scmPathInfoStore.get().get()); + return new AutoCompleteLinks(accessScmPathInfoStore().get()); } static class AutoCompleteLinks { @@ -306,7 +320,7 @@ class ResourceLinks { } ConfigLinks config() { - return new ConfigLinks(scmPathInfoStore.get().get()); + return new ConfigLinks(accessScmPathInfoStore().get()); } static class ConfigLinks { @@ -326,7 +340,7 @@ class ResourceLinks { } AdminInfoLinks adminInfo() { - return new AdminInfoLinks(scmPathInfoStore.get().get()); + return new AdminInfoLinks(accessScmPathInfoStore().get()); } static class AdminInfoLinks { @@ -342,7 +356,7 @@ class ResourceLinks { } public RepositoryLinks repository() { - return new RepositoryLinks(scmPathInfoStore.get().get()); + return new RepositoryLinks(accessScmPathInfoStore().get()); } static class RepositoryLinks { @@ -424,7 +438,7 @@ class ResourceLinks { } RepositoryCollectionLinks repositoryCollection() { - return new RepositoryCollectionLinks(scmPathInfoStore.get().get()); + return new RepositoryCollectionLinks(accessScmPathInfoStore().get()); } static class RepositoryCollectionLinks { @@ -448,7 +462,7 @@ class ResourceLinks { } public NamespaceStrategiesLinks namespaceStrategies() { - return new NamespaceStrategiesLinks(scmPathInfoStore.get().get()); + return new NamespaceStrategiesLinks(accessScmPathInfoStore().get()); } static class NamespaceStrategiesLinks { @@ -465,7 +479,7 @@ class ResourceLinks { } public RepositoryTypeLinks repositoryType() { - return new RepositoryTypeLinks(scmPathInfoStore.get().get()); + return new RepositoryTypeLinks(accessScmPathInfoStore().get()); } static class RepositoryTypeLinks { @@ -481,7 +495,7 @@ class ResourceLinks { } public RepositoryTypeCollectionLinks repositoryTypeCollection() { - return new RepositoryTypeCollectionLinks(scmPathInfoStore.get().get()); + return new RepositoryTypeCollectionLinks(accessScmPathInfoStore().get()); } static class RepositoryTypeCollectionLinks { @@ -498,7 +512,7 @@ class ResourceLinks { public TagCollectionLinks tag() { - return new TagCollectionLinks(scmPathInfoStore.get().get()); + return new TagCollectionLinks(accessScmPathInfoStore().get()); } static class TagCollectionLinks { @@ -526,7 +540,7 @@ class ResourceLinks { } public DiffLinks diff() { - return new DiffLinks(scmPathInfoStore.get().get()); + return new DiffLinks(accessScmPathInfoStore().get()); } static class DiffLinks { @@ -550,7 +564,7 @@ class ResourceLinks { } public BranchLinks branch() { - return new BranchLinks(scmPathInfoStore.get().get()); + return new BranchLinks(accessScmPathInfoStore().get()); } static class BranchLinks { @@ -578,7 +592,7 @@ class ResourceLinks { } public BranchDetailsLinks branchDetails() { - return new BranchDetailsLinks(scmPathInfoStore.get().get()); + return new BranchDetailsLinks(accessScmPathInfoStore().get()); } static class BranchDetailsLinks { @@ -594,7 +608,7 @@ class ResourceLinks { } public BranchDetailsCollectionLinks branchDetailsCollection() { - return new BranchDetailsCollectionLinks(scmPathInfoStore.get().get()); + return new BranchDetailsCollectionLinks(accessScmPathInfoStore().get()); } static class BranchDetailsCollectionLinks { @@ -610,7 +624,7 @@ class ResourceLinks { } public IncomingLinks incoming() { - return new IncomingLinks(scmPathInfoStore.get().get()); + return new IncomingLinks(accessScmPathInfoStore().get()); } static class IncomingLinks { @@ -656,7 +670,7 @@ class ResourceLinks { } public BranchCollectionLinks branchCollection() { - return new BranchCollectionLinks(scmPathInfoStore.get().get()); + return new BranchCollectionLinks(accessScmPathInfoStore().get()); } static class BranchCollectionLinks { @@ -672,7 +686,7 @@ class ResourceLinks { } public ChangesetLinks changeset() { - return new ChangesetLinks(scmPathInfoStore.get().get()); + return new ChangesetLinks(accessScmPathInfoStore().get()); } static class ChangesetLinks { @@ -696,7 +710,7 @@ class ResourceLinks { } public ModificationsLinks modifications() { - return new ModificationsLinks(scmPathInfoStore.get().get()); + return new ModificationsLinks(accessScmPathInfoStore().get()); } static class ModificationsLinks { @@ -712,7 +726,7 @@ class ResourceLinks { } public FileHistoryLinks fileHistory() { - return new FileHistoryLinks(scmPathInfoStore.get().get()); + return new FileHistoryLinks(accessScmPathInfoStore().get()); } static class FileHistoryLinks { @@ -729,7 +743,7 @@ class ResourceLinks { } public SourceLinks source() { - return new SourceLinks(scmPathInfoStore.get().get()); + return new SourceLinks(accessScmPathInfoStore().get()); } static class SourceLinks { @@ -761,7 +775,7 @@ class ResourceLinks { } public AnnotateLinks annotate() { - return new AnnotateLinks(scmPathInfoStore.get().get()); + return new AnnotateLinks(accessScmPathInfoStore().get()); } static class AnnotateLinks { @@ -777,7 +791,7 @@ class ResourceLinks { } RepositoryVerbLinks repositoryVerbs() { - return new RepositoryVerbLinks(scmPathInfoStore.get().get()); + return new RepositoryVerbLinks(accessScmPathInfoStore().get()); } static class RepositoryVerbLinks { @@ -793,7 +807,7 @@ class ResourceLinks { } RepositoryRoleLinks repositoryRole() { - return new RepositoryRoleLinks(scmPathInfoStore.get().get()); + return new RepositoryRoleLinks(accessScmPathInfoStore().get()); } static class RepositoryRoleLinks { @@ -817,7 +831,7 @@ class ResourceLinks { } RepositoryRoleCollectionLinks repositoryRoleCollection() { - return new RepositoryRoleCollectionLinks(scmPathInfoStore.get().get()); + return new RepositoryRoleCollectionLinks(accessScmPathInfoStore().get()); } static class RepositoryRoleCollectionLinks { @@ -837,7 +851,7 @@ class ResourceLinks { } public RepositoryPermissionLinks repositoryPermission() { - return new RepositoryPermissionLinks(scmPathInfoStore.get().get()); + return new RepositoryPermissionLinks(accessScmPathInfoStore().get()); } static class RepositoryPermissionLinks { @@ -873,7 +887,7 @@ class ResourceLinks { } public UIPluginLinks uiPlugin() { - return new UIPluginLinks(scmPathInfoStore.get().get()); + return new UIPluginLinks(accessScmPathInfoStore().get()); } static class UIPluginLinks { @@ -889,7 +903,7 @@ class ResourceLinks { } public UIPluginCollectionLinks uiPluginCollection() { - return new UIPluginCollectionLinks(scmPathInfoStore.get().get()); + return new UIPluginCollectionLinks(accessScmPathInfoStore().get()); } static class UIPluginCollectionLinks { @@ -905,7 +919,7 @@ class ResourceLinks { } public InstalledPluginLinks installedPlugin() { - return new InstalledPluginLinks(scmPathInfoStore.get().get()); + return new InstalledPluginLinks(accessScmPathInfoStore().get()); } static class InstalledPluginLinks { @@ -925,7 +939,7 @@ class ResourceLinks { } public InstalledPluginCollectionLinks installedPluginCollection() { - return new InstalledPluginCollectionLinks(scmPathInfoStore.get().get()); + return new InstalledPluginCollectionLinks(accessScmPathInfoStore().get()); } static class InstalledPluginCollectionLinks { @@ -945,7 +959,7 @@ class ResourceLinks { } public AvailablePluginLinks availablePlugin() { - return new AvailablePluginLinks(scmPathInfoStore.get().get()); + return new AvailablePluginLinks(accessScmPathInfoStore().get()); } static class AvailablePluginLinks { @@ -965,7 +979,7 @@ class ResourceLinks { } public AvailablePluginCollectionLinks availablePluginCollection() { - return new AvailablePluginCollectionLinks(scmPathInfoStore.get().get()); + return new AvailablePluginCollectionLinks(accessScmPathInfoStore().get()); } static class AvailablePluginCollectionLinks { @@ -981,7 +995,7 @@ class ResourceLinks { } public PendingPluginCollectionLinks pendingPluginCollection() { - return new PendingPluginCollectionLinks(scmPathInfoStore.get().get()); + return new PendingPluginCollectionLinks(accessScmPathInfoStore().get()); } static class PendingPluginCollectionLinks { @@ -1005,7 +1019,7 @@ class ResourceLinks { } public AuthenticationLinks authentication() { - return new AuthenticationLinks(scmPathInfoStore.get().get()); + return new AuthenticationLinks(accessScmPathInfoStore().get()); } static class AuthenticationLinks { @@ -1029,7 +1043,7 @@ class ResourceLinks { } public IndexLinks index() { - return new IndexLinks(scmPathInfoStore.get().get()); + return new IndexLinks(accessScmPathInfoStore().get()); } static class IndexLinks { @@ -1045,7 +1059,7 @@ class ResourceLinks { } public PermissionsLinks permissions() { - return new PermissionsLinks(scmPathInfoStore.get().get()); + return new PermissionsLinks(accessScmPathInfoStore().get()); } static class PermissionsLinks { @@ -1061,7 +1075,7 @@ class ResourceLinks { } public NamespaceCollectionLinks namespaceCollection() { - return new NamespaceCollectionLinks(scmPathInfoStore.get().get()); + return new NamespaceCollectionLinks(accessScmPathInfoStore().get()); } static class NamespaceCollectionLinks { @@ -1077,7 +1091,7 @@ class ResourceLinks { } public NamespaceLinks namespace() { - return new NamespaceLinks(scmPathInfoStore.get().get()); + return new NamespaceLinks(accessScmPathInfoStore().get()); } static class NamespaceLinks { @@ -1097,7 +1111,7 @@ class ResourceLinks { } public NamespacePermissionLinks namespacePermission() { - return new NamespacePermissionLinks(scmPathInfoStore.get().get()); + return new NamespacePermissionLinks(accessScmPathInfoStore().get()); } static class NamespacePermissionLinks { @@ -1133,7 +1147,7 @@ class ResourceLinks { } public MetricsLinks metrics() { - return new MetricsLinks(new LinkBuilder(scmPathInfoStore.get().get(), MetricsResource.class)); + return new MetricsLinks(new LinkBuilder(accessScmPathInfoStore().get(), MetricsResource.class)); } public static class MetricsLinks { @@ -1150,7 +1164,7 @@ class ResourceLinks { } public SearchLinks search() { - return new SearchLinks(scmPathInfoStore.get().get()); + return new SearchLinks(accessScmPathInfoStore().get()); } public static class SearchLinks { @@ -1171,7 +1185,7 @@ class ResourceLinks { } public InitialAdminAccountLinks initialAdminAccount() { - return new InitialAdminAccountLinks(new LinkBuilder(scmPathInfoStore.get().get(), InitializationResource.class, AdminAccountStartupResource.class)); + return new InitialAdminAccountLinks(new LinkBuilder(accessScmPathInfoStore().get(), InitializationResource.class, AdminAccountStartupResource.class)); } public static class InitialAdminAccountLinks {