diff --git a/scm-core/src/main/java/sonia/scm/ContextEntry.java b/scm-core/src/main/java/sonia/scm/ContextEntry.java index 591f29972a..bbd2fadc5d 100644 --- a/scm-core/src/main/java/sonia/scm/ContextEntry.java +++ b/scm-core/src/main/java/sonia/scm/ContextEntry.java @@ -35,6 +35,14 @@ public class ContextEntry { public static class ContextBuilder { private final List context = new LinkedList<>(); + public static List noContext() { + return new ContextBuilder().build(); + } + + public static List only(String type, String id) { + return new ContextBuilder().in(type, id).build(); + } + public static ContextBuilder entity(Repository repository) { return new ContextBuilder().in(repository.getNamespaceAndName()); } diff --git a/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java index 255738455c..dd87b77210 100644 --- a/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java +++ b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java @@ -13,6 +13,11 @@ public abstract class ExceptionWithContext extends RuntimeException { this.context = context; } + public ExceptionWithContext(List context, String message, Exception cause) { + super(message, cause); + this.context = context; + } + public List getContext() { return unmodifiableList(context); } diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java index 997413aacb..6cfa08975e 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java @@ -40,6 +40,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.AlreadyExistsException; import sonia.scm.ConfigurationException; +import sonia.scm.ContextEntry; import sonia.scm.io.CommandResult; import sonia.scm.io.ExtendedCommand; import sonia.scm.io.FileSystem; @@ -128,7 +129,7 @@ public abstract class AbstractSimpleRepositoryHandler context, String message, Exception cause) { + super(context, message, cause); + } + + @Override + public String getCode() { + return null; } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 13340a20e7..4524822a6a 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.ContextEntry; import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; import sonia.scm.web.GitUserAgentProvider; @@ -203,7 +204,7 @@ public final class GitUtil } catch (GitAPIException ex) { - throw new InternalRepositoryException("could not fetch", ex); + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("remote", directory.toString()).in(remoteRepository), "could not fetch", ex); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java index e90a1c11ed..3cf72166ea 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java @@ -160,7 +160,7 @@ public abstract class AbstractGitIncomingOutgoingCommand } catch (Exception ex) { - throw new InternalRepositoryException("could not execute incoming command", ex); + throw new InternalRepositoryException(repository, "could not execute incoming command", ex); } finally { @@ -200,13 +200,7 @@ public abstract class AbstractGitIncomingOutgoingCommand { if (e.getKey().startsWith(prefix)) { - if (ref != null) - { - throw new InternalRepositoryException("could not find remote branch"); - } - ref = e.getValue(); - break; } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitPushOrPullCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitPushOrPullCommand.java index 75050c26ea..e4e37d6fed 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitPushOrPullCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitPushOrPullCommand.java @@ -114,7 +114,7 @@ public abstract class AbstractGitPushOrPullCommand extends AbstractGitCommand } catch (Exception ex) { - throw new InternalRepositoryException("could not execute push/pull command", ex); + throw new InternalRepositoryException(repository, "could not execute push/pull command", ex); } return counter; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java index f50f245963..2ad38648da 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java @@ -55,6 +55,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static sonia.scm.ContextEntry.ContextBuilder.entity; + //~--- JDK imports ------------------------------------------------------------ /** @@ -108,9 +110,8 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand if (gitBlameResult == null) { - throw new InternalRepositoryException( - "could not create blame result for path ".concat( - request.getPath())); + throw new InternalRepositoryException(entity("path", request.getPath()).in(repository), + "could not create blame result for path"); } List blameLines = new ArrayList(); @@ -150,7 +151,7 @@ public class GitBlameCommand extends AbstractGitCommand implements BlameCommand } catch (GitAPIException ex) { - throw new InternalRepositoryException("could not create blame view", ex); + throw new InternalRepositoryException(repository, "could not create blame view", ex); } return result; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java index 0cc47100de..4922752b6f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java @@ -102,7 +102,7 @@ public class GitBranchesCommand extends AbstractGitCommand } catch (GitAPIException ex) { - throw new InternalRepositoryException("could not read branches", ex); + throw new InternalRepositoryException(repository, "could not read branches", ex); } return branches; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 8a3745dce7..f8a5b79a8b 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -254,7 +254,7 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand } catch (Exception ex) { - throw new InternalRepositoryException("could not create change log", ex); + throw new InternalRepositoryException(repository, "could not create change log", ex); } finally { diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModificationsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModificationsCommand.java index 2b35ba74f6..5040069c12 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModificationsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModificationsCommand.java @@ -17,6 +17,8 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.List; +import static sonia.scm.ContextEntry.ContextBuilder.entity; + @Slf4j public class GitModificationsCommand extends AbstractGitCommand implements ModificationsCommand { @@ -26,7 +28,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif } private Modifications createModifications(TreeWalk treeWalk, RevCommit commit, RevWalk revWalk, String revision) - throws IOException, UnsupportedModificationTypeException { + throws IOException { treeWalk.reset(); treeWalk.setRecursive(true); if (commit.getParentCount() > 0) { @@ -73,12 +75,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif } } catch (IOException ex) { log.error("could not open repository", ex); - throw new InternalRepositoryException(ex); - - } catch (UnsupportedModificationTypeException ex) { - log.error("Unsupported modification type", ex); - throw new InternalRepositoryException(ex); - + throw new InternalRepositoryException(entity(repository), "could not open repository", ex); } finally { GitUtil.release(revWalk); GitUtil.close(gitRepository); @@ -100,7 +97,7 @@ public class GitModificationsCommand extends AbstractGitCommand implements Modif } else if (type == DiffEntry.ChangeType.DELETE) { modifications.getRemoved().add(entry.getOldPath()); } else { - throw new UnsupportedModificationTypeException(MessageFormat.format("The modification type: {0} is not supported.", type)); + throw new UnsupportedModificationTypeException(entity(repository), MessageFormat.format("The modification type: {0} is not supported.", type)); } } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPullCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPullCommand.java index a7b341ff5d..bb06e1fd9d 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPullCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPullCommand.java @@ -249,7 +249,7 @@ public class GitPullCommand extends AbstractGitPushOrPullCommand } catch (GitAPIException ex) { - throw new InternalRepositoryException("error durring pull", ex); + throw new InternalRepositoryException(repository, "error during pull", ex); } return response; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java index 02fee3cef0..807ec807e6 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitTagsCommand.java @@ -95,7 +95,7 @@ public class GitTagsCommand extends AbstractGitCommand implements TagsCommand } catch (GitAPIException ex) { - throw new InternalRepositoryException("could not read tags from repository", ex); + throw new InternalRepositoryException(repository, "could not read tags from repository", ex); } finally { diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/UnsupportedModificationTypeException.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/UnsupportedModificationTypeException.java index 5081a29d21..85119a3e9f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/UnsupportedModificationTypeException.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/UnsupportedModificationTypeException.java @@ -1,9 +1,10 @@ package sonia.scm.repository.spi; +import sonia.scm.ContextEntry; import sonia.scm.repository.InternalRepositoryException; public class UnsupportedModificationTypeException extends InternalRepositoryException { - public UnsupportedModificationTypeException(String message) { - super(message); + public UnsupportedModificationTypeException(ContextEntry.ContextBuilder entity, String message) { + super(entity, message); } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java index 19cfd37665..4115a514a2 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java @@ -272,7 +272,7 @@ public class AbstractHgHandler } catch (JAXBException ex) { logger.error("could not parse result", ex); - throw new InternalRepositoryException("could not parse result", ex); + throw new InternalRepositoryException(repository, "could not parse result", ex); } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java index 554d6aaf05..6309720f75 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java @@ -36,6 +36,9 @@ package sonia.scm.repository.spi; import com.aragost.javahg.commands.ExecutionException; import com.google.common.io.ByteStreams; import com.google.common.io.Closeables; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.ContextEntry; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Repository; import sonia.scm.web.HgUtil; @@ -46,6 +49,8 @@ import java.io.OutputStream; public class HgCatCommand extends AbstractCommand implements CatCommand { + private static final Logger log = LoggerFactory.getLogger(HgCatCommand.class); + HgCatCommand(HgCommandContext context, Repository repository) { super(context, repository); } @@ -70,7 +75,8 @@ public class HgCatCommand extends AbstractCommand implements CatCommand { try { return cmd.execute(request.getPath()); } catch (ExecutionException e) { - throw new InternalRepositoryException(e); + log.error("could not execute cat command", e); + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity(getRepository()), "could not execute cat command", e); } } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgIncomingCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgIncomingCommand.java index 55cf0fbe01..c60f2c5712 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgIncomingCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgIncomingCommand.java @@ -103,7 +103,7 @@ public class HgIncomingCommand extends AbstractCommand } else { - throw new InternalRepositoryException("could not execute incoming command", ex); + throw new InternalRepositoryException(getRepository(), "could not execute incoming command", ex); } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgOutgoingCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgOutgoingCommand.java index b476b6c2ab..81bee6b9ff 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgOutgoingCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgOutgoingCommand.java @@ -103,7 +103,7 @@ public class HgOutgoingCommand extends AbstractCommand } else { - throw new InternalRepositoryException("could not execute outgoing command", ex); + throw new InternalRepositoryException(getRepository(), "could not execute outgoing command", ex); } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java index 0eb23ef4e7..1d130a0f79 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPullCommand.java @@ -97,7 +97,7 @@ public class HgPullCommand extends AbstractHgPushOrPullCommand } catch (ExecutionException ex) { - throw new InternalRepositoryException("could not execute push command", ex); + throw new InternalRepositoryException(getRepository(), "could not execute push command", ex); } return new PullResponse(result.size()); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPushCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPushCommand.java index fb0a1a1c73..b1c12037db 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPushCommand.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgPushCommand.java @@ -97,7 +97,7 @@ public class HgPushCommand extends AbstractHgPushOrPullCommand } catch (ExecutionException ex) { - throw new InternalRepositoryException("could not execute push command", ex); + throw new InternalRepositoryException(getRepository(), "could not execute push command", ex); } return new PushResponse(result.size()); diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java index 7d5c9695c9..cd242faa2d 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java @@ -56,6 +56,8 @@ import sonia.scm.util.Util; import java.io.File; +import static sonia.scm.ContextEntry.ContextBuilder.entity; + //~--- JDK imports ------------------------------------------------------------ /** @@ -173,7 +175,8 @@ public class SvnRepositoryHandler } catch (SVNException ex) { - throw new InternalRepositoryException(ex); + logger.error("could not create svn repository", ex); + throw new InternalRepositoryException(entity(repository), "could not create repository", ex); } finally { diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java index fe9a72ffce..b589734d03 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java @@ -98,7 +98,7 @@ public class SvnBlameCommand extends AbstractSvnCommand implements BlameCommand } catch (SVNException ex) { - throw new InternalRepositoryException("could not create blame result", ex); + throw new InternalRepositoryException(repository, "could not create blame result", ex); } return new BlameResult(blameLines.size(), blameLines); diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java index 9a5c39af46..9ee43b2259 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java @@ -137,7 +137,7 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand } else if (SVNErrorCode.FS_NO_SUCH_REVISION.getCode() == svnErrorCode) { throw notFound(entity("Revision", request.getRevision()).in(repository)); } else { - throw new InternalRepositoryException("could not get content from revision", ex); + throw new InternalRepositoryException(repository, "could not get content from revision", ex); } } @@ -157,7 +157,7 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand } catch (SVNException ex) { - throw new InternalRepositoryException("could not get content from transaction", ex); + throw new InternalRepositoryException(repository, "could not get content from transaction", ex); } finally { diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java index 9e81f1a7a9..8418fd63b8 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java @@ -120,7 +120,7 @@ public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand } catch (SVNException ex) { - throw new InternalRepositoryException("could not create diff", ex); + throw new InternalRepositoryException(repository, "could not create diff", ex); } finally { diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java index a29b8f4a0c..be102be1bd 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java @@ -97,7 +97,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand } catch (SVNException ex) { - throw new InternalRepositoryException("could not open repository", ex); + throw new InternalRepositoryException(repository, "could not open repository", ex); } return changeset; @@ -139,7 +139,7 @@ public class SvnLogCommand extends AbstractSvnCommand implements LogCommand } catch (SVNException ex) { - throw new InternalRepositoryException("could not open repository", ex); + throw new InternalRepositoryException(repository, "could not open repository", ex); } return changesets; diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModificationsCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModificationsCommand.java index 00fb1dc5a0..4b4f655b12 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModificationsCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnModificationsCommand.java @@ -34,7 +34,7 @@ public class SvnModificationsCommand extends AbstractSvnCommand implements Modif modifications = SvnUtil.createModifications(entries.iterator().next(), revision); } } catch (SVNException ex) { - throw new InternalRepositoryException("could not open repository", ex); + throw new InternalRepositoryException(repository, "could not open repository", ex); } return modifications; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/ContextualExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/rest/ContextualExceptionMapper.java index 43b8a38ccc..97d29aaa0f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/ContextualExceptionMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/ContextualExceptionMapper.java @@ -26,7 +26,7 @@ public class ContextualExceptionMapper implement @Override public Response toResponse(E exception) { - logger.debug("map {} to status code {}", type.getSimpleName(), status.getStatusCode()); + logger.debug("map {} to status code {}", type.getSimpleName(), status.getStatusCode(), exception); return Response.status(status) .entity(mapper.map(exception)) .type(VndMediaType.ERROR_TYPE) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java index faa7f4975c..017568b613 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryRootResource.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import sonia.scm.PageResult; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; -import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.api.RepositoryService; @@ -24,6 +23,9 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; +import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; + @Slf4j public class FileHistoryRootResource { @@ -66,7 +68,8 @@ public class FileHistoryRootResource { @PathParam("path") String path, @DefaultValue("0") @QueryParam("page") int page, @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException { - try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name); + try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) { log.info("Get changesets of the file {} and revision {}", path, revision); Repository repository = repositoryService.getRepository(); ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService) @@ -80,9 +83,9 @@ public class FileHistoryRootResource { PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); return Response.ok(fileHistoryCollectionToDtoMapper.map(page, pageSize, pageResult, repository, revision, path)).build(); } else { - String message = String.format("for the revision %s and the file %s there is no changesets", revision, path); + String message = String.format("for the revision %s and the file %s there are no changesets", revision, path); log.error(message); - throw new InternalRepositoryException(message); + throw notFound(entity("path", path).in("revision", revision).in(namespaceAndName)); } } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/InternalRepositoryExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/InternalRepositoryExceptionMapper.java index d30677c5f7..856a9310a0 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/InternalRepositoryExceptionMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/InternalRepositoryExceptionMapper.java @@ -1,15 +1,17 @@ package sonia.scm.api.v2.resources; -import sonia.scm.api.rest.StatusExceptionMapper; +import sonia.scm.api.rest.ContextualExceptionMapper; import sonia.scm.repository.InternalRepositoryException; +import javax.inject.Inject; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; @Provider -public class InternalRepositoryExceptionMapper extends StatusExceptionMapper { +public class InternalRepositoryExceptionMapper extends ContextualExceptionMapper { - public InternalRepositoryExceptionMapper() { - super(InternalRepositoryException.class, Response.Status.INTERNAL_SERVER_ERROR); + @Inject + public InternalRepositoryExceptionMapper(ExceptionWithContextToErrorDtoMapper mapper) { + super(InternalRepositoryException.class, Response.Status.INTERNAL_SERVER_ERROR, mapper); } } diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java index 6c903815a7..c409a860ec 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java @@ -143,7 +143,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { try { getHandler(newRepository).create(newRepository); } catch (AlreadyExistsException e) { - throw new InternalRepositoryException("directory for repository does already exist", e); + throw new InternalRepositoryException(repository, "directory for repository does already exist", e); } } fireEvent(HandlerEventType.BEFORE_CREATE, newRepository); @@ -353,9 +353,9 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager { RepositoryHandler handler = handlerMap.get(type); if (handler == null) { - throw new InternalRepositoryException("could not find handler for " + type); + throw new InternalRepositoryException(entity(repository), "could not find handler for " + type); } else if (!handler.isConfigured()) { - throw new InternalRepositoryException("handler is not configured for type " + type); + throw new InternalRepositoryException(entity(repository), "handler is not configured for type " + type); } return handler; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java index 4bda5c875d..4b3e21fa60 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/DispatcherMock.java @@ -17,7 +17,7 @@ public class DispatcherMock { dispatcher.getProviderFactory().register(new AlreadyExistsExceptionMapper(mapper)); dispatcher.getProviderFactory().register(new ConcurrentModificationExceptionMapper(mapper)); dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class); - dispatcher.getProviderFactory().registerProvider(InternalRepositoryExceptionMapper.class); + dispatcher.getProviderFactory().register(new InternalRepositoryExceptionMapper(mapper)); dispatcher.getProviderFactory().register(new ChangePasswordNotAllowedExceptionMapper(mapper)); dispatcher.getProviderFactory().register(new InvalidPasswordExceptionMapper(mapper)); dispatcher.getProviderFactory().registerProvider(IllegalArgumentExceptionMapper.class); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java index 3898ac07e0..52c9a434c0 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/FileHistoryResourceTest.java @@ -8,7 +8,6 @@ import org.apache.shiro.util.ThreadContext; import org.apache.shiro.util.ThreadState; import org.assertj.core.util.Lists; import org.jboss.resteasy.core.Dispatcher; -import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; import org.junit.After; @@ -18,9 +17,8 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.ContextEntry; import sonia.scm.NotFoundException; -import sonia.scm.api.rest.AuthorizationExceptionMapper; -import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.InternalRepositoryException; @@ -168,7 +166,7 @@ public class FileHistoryResourceTest extends RepositoryTestBase { when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); when(logCommandBuilder.setStartChangeset(eq(id))).thenReturn(logCommandBuilder); when(logCommandBuilder.setPath(eq(path))).thenReturn(logCommandBuilder); - when(logCommandBuilder.getChangesets()).thenThrow(InternalRepositoryException.class); + when(logCommandBuilder.getChangesets()).thenThrow(new InternalRepositoryException(ContextEntry.ContextBuilder.noContext(), "", new RuntimeException())); MockHttpRequest request = MockHttpRequest .get(FILE_HISTORY_URL + id + "/" + path) @@ -179,7 +177,7 @@ public class FileHistoryResourceTest extends RepositoryTestBase { } @Test - public void shouldGet500OnNullChangesets() throws Exception { + public void shouldGet404OnNullChangesets() throws Exception { String id = "revision_123"; String path = "root_dir/sub_dir/file-to-inspect.txt"; @@ -194,6 +192,6 @@ public class FileHistoryResourceTest extends RepositoryTestBase { .accept(VndMediaType.CHANGESET_COLLECTION); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); - assertEquals(500, response.getStatus()); + assertEquals(404, response.getStatus()); } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java index b3eacf314e..fc4598081d 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ModificationsResourceTest.java @@ -8,7 +8,6 @@ import org.apache.shiro.util.ThreadContext; import org.apache.shiro.util.ThreadState; import org.assertj.core.util.Lists; import org.jboss.resteasy.core.Dispatcher; -import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; import org.junit.After; @@ -18,8 +17,6 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import sonia.scm.api.rest.AuthorizationExceptionMapper; -import sonia.scm.api.v2.NotFoundExceptionMapper; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Modifications; import sonia.scm.repository.NamespaceAndName; @@ -38,6 +35,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static sonia.scm.ContextEntry.ContextBuilder.noContext; @Slf4j @RunWith(MockitoJUnitRunner.Silent.class) @@ -72,7 +70,7 @@ public class ModificationsResourceTest extends RepositoryTestBase { @Before - public void prepareEnvironment() throws Exception { + public void prepareEnvironment() { modificationsRootResource = new ModificationsRootResource(serviceFactory, modificationsToDtoMapper); super.modificationsRootResource = Providers.of(modificationsRootResource); dispatcher = DispatcherMock.createDispatcher(getRepositoryRootResource()); @@ -106,7 +104,7 @@ public class ModificationsResourceTest extends RepositoryTestBase { @Test public void shouldGet500OnModificationsCommandError() throws Exception { when(modificationsCommandBuilder.revision(any())).thenReturn(modificationsCommandBuilder); - when(modificationsCommandBuilder.getModifications()).thenThrow(InternalRepositoryException.class); + when(modificationsCommandBuilder.getModifications()).thenThrow(new InternalRepositoryException(noContext(), "", new RuntimeException())); MockHttpRequest request = MockHttpRequest .get(MODIFICATIONS_URL + "revision")