Browse Source

transport: Add ReceiveCommandErrorHandler

This gives a chance to handle an exception for a user. For example, when
an IOException is thrown while executing
`walk.parseAny(cmd.getNewId())`, it's always handled as
REJECTED_MISSING_OBJECT. However, IOException can mean a Git storage IO
error. By introducing an error handler class, a user can add a custom
error handler for these cases.

Change-Id: I3e03a536e1d8e137cb0f6e596d71642e72adde9e
Signed-off-by: Masaya Suzuki <masayasuzuki@google.com>
tags/v5.7.0.202001151323-m1
Masaya Suzuki 4 years ago
parent
commit
a91489f4a8

+ 83
- 0
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommandErrorHandler.java View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2019, Google LLC and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.transport;

import java.io.IOException;
import java.util.List;

import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.transport.ReceiveCommand.Result;

/**
* Exception handler for processing {@link ReceiveCommand}.
*
* @since 5.7
*/
public interface ReceiveCommandErrorHandler {
/**
* Handle an exception thrown while validating the new commit ID.
*
* @param cmd
* offending command
* @param e
* exception thrown
*/
default void handleNewIdValidationException(ReceiveCommand cmd,
IOException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getNewId().name());
}

/**
* Handle an exception thrown while validating the old commit ID.
*
* @param cmd
* offending command
* @param e
* exception thrown
*/
default void handleOldIdValidationException(ReceiveCommand cmd,
IOException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getOldId().name());
}

/**
* Handle an exception thrown while checking if the update is fast-forward.
*
* @param cmd
* offending command
* @param e
* exception thrown
*/
default void handleFastForwardCheckException(ReceiveCommand cmd,
IOException e) {
if (e instanceof MissingObjectException) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT, e.getMessage());
} else {
cmd.setResult(Result.REJECTED_OTHER_REASON);
}
}

/**
* Handle an exception thrown while checking if the update is fast-forward.
*
* @param cmds
* commands being processed
* @param e
* exception thrown
*/
default void handleBatchRefUpdateException(List<ReceiveCommand> cmds,
IOException e) {
for (ReceiveCommand cmd : cmds) {
if (cmd.getResult() == Result.NOT_ATTEMPTED) {
cmd.reject(e);
}
}
}
}

+ 28
- 17
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java View File

@@ -295,6 +295,10 @@ public class ReceivePack {
/** Hook to validate the update commands before execution. */
private PreReceiveHook preReceive;

private ReceiveCommandErrorHandler receiveCommandErrorHandler = new ReceiveCommandErrorHandler() {
// Use the default implementation.
};

/** Hook to report on the commands after execution. */
private PostReceiveHook postReceive;

@@ -1020,6 +1024,17 @@ public class ReceivePack {
return Collections.unmodifiableList(commands);
}

/**
* Set an error handler for {@link ReceiveCommand}.
*
* @param receiveCommandErrorHandler
* @since 5.7
*/
public void setReceiveCommandErrorHandler(
ReceiveCommandErrorHandler receiveCommandErrorHandler) {
this.receiveCommandErrorHandler = receiveCommandErrorHandler;
}

/**
* Send an error message to the client.
* <p>
@@ -1726,16 +1741,16 @@ public class ReceivePack {
try {
oldObj = walk.parseAny(cmd.getOldId());
} catch (IOException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT,
cmd.getOldId().name());
receiveCommandErrorHandler
.handleOldIdValidationException(cmd, e);
continue;
}

try {
newObj = walk.parseAny(cmd.getNewId());
} catch (IOException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT,
cmd.getNewId().name());
receiveCommandErrorHandler
.handleNewIdValidationException(cmd, e);
continue;
}

@@ -1743,16 +1758,14 @@ public class ReceivePack {
&& newObj instanceof RevCommit) {
try {
if (walk.isMergedInto((RevCommit) oldObj,
(RevCommit) newObj))
(RevCommit) newObj)) {
cmd.setTypeFastForwardUpdate();
else
cmd.setType(
ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
} catch (MissingObjectException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT,
e.getMessage());
} else {
cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
}
} catch (IOException e) {
cmd.setResult(Result.REJECTED_OTHER_REASON);
receiveCommandErrorHandler
.handleFastForwardCheckException(cmd, e);
}
} else {
cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
@@ -1831,11 +1844,9 @@ public class ReceivePack {
try {
batch.setPushCertificate(getPushCertificate());
batch.execute(walk, updating);
} catch (IOException err) {
for (ReceiveCommand cmd : toApply) {
if (cmd.getResult() == Result.NOT_ATTEMPTED)
cmd.reject(err);
}
} catch (IOException e) {
receiveCommandErrorHandler.handleBatchRefUpdateException(toApply,
e);
}
}


Loading…
Cancel
Save