Skip to content

Commit 820316f

Browse files
committed
polish
1 parent fa878be commit 820316f

File tree

19 files changed

+126
-53
lines changed

19 files changed

+126
-53
lines changed

client/java-armeria/src/main/java/com/linecorp/centraldogma/internal/client/armeria/ArmeriaCentralDogma.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@
105105
import com.linecorp.centraldogma.common.Revision;
106106
import com.linecorp.centraldogma.common.RevisionNotFoundException;
107107
import com.linecorp.centraldogma.common.ShuttingDownException;
108-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
108+
import com.linecorp.centraldogma.common.TextPatchConflictException;
109+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
109110
import com.linecorp.centraldogma.internal.HistoryConstants;
110111
import com.linecorp.centraldogma.internal.Jackson;
111112
import com.linecorp.centraldogma.internal.Util;
@@ -138,7 +139,8 @@ public final class ArmeriaCentralDogma extends AbstractCentralDogma {
138139
.put(ReadOnlyException.class.getName(), ReadOnlyException::new)
139140
.put(MirrorException.class.getName(), MirrorException::new)
140141
.put(PermissionException.class.getName(), PermissionException::new)
141-
.put(JsonPatchException.class.getName(), JsonPatchException::new)
142+
.put(JsonPatchConflictException.class.getName(), JsonPatchConflictException::new)
143+
.put(TextPatchConflictException.class.getName(), TextPatchConflictException::new)
142144
.build();
143145

144146
private final WebClient client;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2025 LINE Corporation
3+
*
4+
* LINE Corporation licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*
16+
*/
17+
18+
package com.linecorp.centraldogma.common;
19+
20+
/**
21+
* A {@link CentralDogmaException} that is raised when attempted to apply a text patch which cannot be applied
22+
* without a conflict.
23+
*/
24+
public final class TextPatchConflictException extends ChangeConflictException {
25+
private static final long serialVersionUID = -6150468151945332532L;
26+
27+
/**
28+
* Creates a new instance.
29+
*/
30+
public TextPatchConflictException(String message) {
31+
super(message);
32+
}
33+
34+
/**
35+
* Creates a new instance with the specified {@code cause}.
36+
*/
37+
public TextPatchConflictException(String message, Throwable cause) {
38+
super(message, cause);
39+
}
40+
}

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/AddOperation.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ static JsonNode addToArray(final JsonPointer path, final JsonNode node, final Js
9999
try {
100100
index = Integer.parseInt(rawToken);
101101
} catch (NumberFormatException ignored) {
102-
throw new JsonPatchException("not an index: " + rawToken + " (expected: a non-negative integer)");
102+
throw new JsonPatchConflictException("not an index: " + rawToken + " (expected: a non-negative integer)");
103103
}
104104

105105
if (index < 0 || index > size) {
106-
throw new JsonPatchException("index out of bounds: " + index +
107-
" (expected: >= 0 && <= " + size + ')');
106+
throw new JsonPatchConflictException("index out of bounds: " + index +
107+
" (expected: >= 0 && <= " + size + ')');
108108
}
109109

110110
target.insert(index, value);

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/CopyOperation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public JsonNode apply(final JsonNode node) {
4848
final JsonPointer from = from();
4949
JsonNode source = node.at(from);
5050
if (source.isMissingNode()) {
51-
throw new JsonPatchException("non-existent source path: " + from);
51+
throw new JsonPatchConflictException("non-existent source path: " + from);
5252
}
5353

5454
final JsonPointer path = path();

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/JsonPatchException.java common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/JsonPatchConflictException.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,26 @@
1717
package com.linecorp.centraldogma.common.jsonpatch;
1818

1919
import com.linecorp.centraldogma.common.CentralDogmaException;
20+
import com.linecorp.centraldogma.common.ChangeConflictException;
2021

2122
/**
22-
* An exception raised when a JSON Patch operation fails.
23+
* A {@link CentralDogmaException} raised when a JSON Patch operation fails.
2324
*/
24-
public final class JsonPatchException extends CentralDogmaException {
25+
public final class JsonPatchConflictException extends ChangeConflictException {
2526

2627
private static final long serialVersionUID = 4746173383862473527L;
2728

2829
/**
2930
* Creates a new instance.
3031
*/
31-
public JsonPatchException(final String message) {
32+
public JsonPatchConflictException(String message) {
3233
super(message);
3334
}
3435

3536
/**
3637
* Creates a new instance with the specified {@code cause}.
3738
*/
38-
public JsonPatchException(final String message, final Throwable cause) {
39+
public JsonPatchConflictException(String message, Throwable cause) {
3940
super(message, cause);
4041
}
4142
}

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/JsonPatchOperation.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ public final JsonPointer path() {
230230
*
231231
* @param node the value to patch
232232
* @return the patched value
233-
* @throws JsonPatchException operation failed to apply to this value
233+
* @throws JsonPatchConflictException operation failed to apply to this value
234234
*/
235235
public abstract JsonNode apply(JsonNode node);
236236

@@ -244,7 +244,7 @@ public JsonNode toJsonNode() {
244244
JsonNode ensureExistence(JsonNode node) {
245245
final JsonNode found = node.at(path);
246246
if (found.isMissingNode()) {
247-
throw new JsonPatchException("non-existent path: " + path);
247+
throw new JsonPatchConflictException("non-existent path: " + path);
248248
}
249249
return found;
250250
}
@@ -265,11 +265,11 @@ private static JsonNode ensureParent(JsonNode node, JsonPointer path, String typ
265265
final JsonPointer parentPath = path.head();
266266
final JsonNode parentNode = node.at(parentPath);
267267
if (parentNode.isMissingNode()) {
268-
throw new JsonPatchException("non-existent " + typeName + " parent: " + parentPath);
268+
throw new JsonPatchConflictException("non-existent " + typeName + " parent: " + parentPath);
269269
}
270270
if (!parentNode.isContainerNode()) {
271-
throw new JsonPatchException(typeName + " parent is not a container: " + parentPath +
272-
" (" + parentNode.getNodeType() + ')');
271+
throw new JsonPatchConflictException(typeName + " parent is not a container: " + parentPath +
272+
" (" + parentNode.getNodeType() + ')');
273273
}
274274
return parentNode;
275275
}

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/MoveOperation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public JsonNode apply(final JsonNode node) {
7575
return node;
7676
}
7777
if (node.at(from).isMissingNode()) {
78-
throw new JsonPatchException("non-existent source path: " + from);
78+
throw new JsonPatchConflictException("non-existent source path: " + from);
7979
}
8080

8181
final JsonNode sourceParent = ensureSourceParent(node, from);

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/PathValueOperation.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ JsonNode valueCopy() {
6767

6868
void ensureEquivalence(JsonNode actual) {
6969
if (!EQUIVALENCE.equivalent(actual, value)) {
70-
throw new JsonPatchException("mismatching value at '" + path() + "': " +
71-
actual + " (expected: " + value + ')');
70+
throw new JsonPatchConflictException("mismatching value at '" + path() + "': " +
71+
actual + " (expected: " + value + ')');
7272
}
7373
}
7474

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/SafeReplaceOperation.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ public JsonNode apply(JsonNode node) {
8585

8686
final JsonPointer path = path();
8787
if (!EQUIVALENCE.equivalent(actual, oldValue)) {
88-
throw new JsonPatchException("mismatching value at '" + path + "': " +
89-
actual + " (expected: " + oldValue + ')');
88+
throw new JsonPatchConflictException("mismatching value at '" + path + "': " +
89+
actual + " (expected: " + oldValue + ')');
9090
}
9191
final JsonNode replacement = newValue.deepCopy();
9292
if (path.toString().isEmpty()) {

common/src/main/java/com/linecorp/centraldogma/common/jsonpatch/TestAbsenceOperation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public JsonNode apply(JsonNode node) {
5151
final JsonPointer path = path();
5252
final JsonNode found = node.at(path);
5353
if (!found.isMissingNode()) {
54-
throw new JsonPatchException("existent path: " + path);
54+
throw new JsonPatchConflictException("existent path: " + path);
5555
}
5656
return node;
5757
}

common/src/main/java/com/linecorp/centraldogma/internal/jsonpatch/JsonPatch.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
import com.google.common.collect.Iterators;
6363
import com.google.common.collect.Sets;
6464

65-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
65+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
6666
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchOperation;
6767
import com.linecorp.centraldogma.internal.Jackson;
6868

@@ -141,7 +141,7 @@ public static JsonPatch fromJson(final JsonNode node) throws IOException {
141141
try {
142142
return Jackson.treeToValue(node, JsonPatch.class);
143143
} catch (JsonMappingException e) {
144-
throw new JsonPatchException("invalid JSON patch", e);
144+
throw new JsonPatchConflictException("invalid JSON patch", e);
145145
}
146146
}
147147

@@ -341,7 +341,7 @@ public List<JsonPatchOperation> operations() {
341341
*
342342
* @param node the value to apply the patch to
343343
* @return the patched JSON value
344-
* @throws JsonPatchException failed to apply patch
344+
* @throws JsonPatchConflictException failed to apply patch
345345
* @throws NullPointerException input is null
346346
*/
347347
public JsonNode apply(final JsonNode node) {

common/src/test/java/com/linecorp/centraldogma/common/jsonpatch/JsonPatchOperationIntegrationTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void testRemove() throws JsonParseException {
129129
.push()
130130
.join())
131131
.isInstanceOf(CompletionException.class)
132-
.hasCauseInstanceOf(JsonPatchException.class)
132+
.hasCauseInstanceOf(JsonPatchConflictException.class)
133133
.hasMessageContaining("failed to apply JSON patch:")
134134
.hasMessageContaining("path=/a.json, content=[{\"op\":\"remove\",\"path\":\"/a\"}]");
135135
}
@@ -194,7 +194,7 @@ void safeReplace() throws JsonParseException {
194194
.push()
195195
.join();
196196
}).isInstanceOf(CompletionException.class)
197-
.hasCauseInstanceOf(JsonPatchException.class)
197+
.hasCauseInstanceOf(JsonPatchConflictException.class)
198198
.hasMessageContaining(
199199
"failed to apply JSON patch: Change{type=APPLY_JSON_PATCH, path=/a.json, " +
200200
"content=[{\"op\":\"safeReplace\",\"path\":\"/a\",\"oldValue\":3,\"value\":4}]}");
@@ -218,7 +218,7 @@ void test() {
218218
.push()
219219
.join();
220220
}).isInstanceOf(CompletionException.class)
221-
.hasCauseInstanceOf(JsonPatchException.class)
221+
.hasCauseInstanceOf(JsonPatchConflictException.class)
222222
.hasMessageContaining(
223223
"failed to apply JSON patch: Change{type=APPLY_JSON_PATCH, " +
224224
"path=/a.json, content=[{\"op\":\"test\",\"path\":\"/a\",\"value\":2}]}");
@@ -242,7 +242,7 @@ void testAbsence() {
242242
.push()
243243
.join();
244244
}).isInstanceOf(CompletionException.class)
245-
.hasCauseInstanceOf(JsonPatchException.class)
245+
.hasCauseInstanceOf(JsonPatchConflictException.class)
246246
.hasMessageContaining(
247247
"failed to apply JSON patch: Change{type=APPLY_JSON_PATCH, " +
248248
"path=/a.json, content=[{\"op\":\"testAbsence\",\"path\":\"/a\"}]}");

common/src/test/java/com/linecorp/centraldogma/internal/jsonpatch/JsonPatchOperationTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import com.google.common.base.Equivalence;
5252
import com.google.common.collect.ImmutableList;
5353

54-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
54+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
5555
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchOperation;
5656

5757
class JsonPatchOperationTest {
@@ -79,7 +79,7 @@ void errorsAreCorrectlyReported(JsonNode patch, JsonNode node, String message) t
7979
final JsonPatchOperation op = READER.readValue(patch);
8080

8181
assertThatThrownBy(() -> op.apply(node))
82-
.isInstanceOf(JsonPatchException.class)
82+
.isInstanceOf(JsonPatchConflictException.class)
8383
.hasMessage(message);
8484
}
8585

common/src/test/java/com/linecorp/centraldogma/internal/jsonpatch/JsonPatchTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
5353
import com.google.common.collect.ImmutableList;
5454

55-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
55+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
5656
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchOperation;
5757

5858
class JsonPatchTest {
@@ -99,12 +99,12 @@ void operationsAreCalledInOrder() {
9999
void whenOneOperationFailsNextOperationIsNotCalled() {
100100
final String message = "foo";
101101
when(op1.apply(any(JsonNode.class)))
102-
.thenThrow(new JsonPatchException(message));
102+
.thenThrow(new JsonPatchConflictException(message));
103103

104104
final JsonPatch patch = new JsonPatch(ImmutableList.of(op1, op2));
105105

106106
assertThatThrownBy(() -> patch.apply(FACTORY.nullNode()))
107-
.isInstanceOf(JsonPatchException.class)
107+
.isInstanceOf(JsonPatchConflictException.class)
108108
.hasMessage(message);
109109

110110
verifyNoMoreInteractions(op2);

common/src/test/java/com/linecorp/centraldogma/internal/jsonpatch/JsonPatchTestSuite.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
import com.fasterxml.jackson.databind.ObjectMapper;
5050
import com.google.common.collect.ImmutableList;
5151

52-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
52+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
5353

5454
class JsonPatchTestSuite {
5555

@@ -64,7 +64,7 @@ void testSuite(JsonNode source, JsonPatch patch, JsonNode expected, boolean vali
6464
assertThat((Object) actual).isEqualTo(expected);
6565
} else {
6666
assertThatThrownBy(() -> patch.apply(source))
67-
.isInstanceOf(JsonPatchException.class);
67+
.isInstanceOf(JsonPatchConflictException.class);
6868
}
6969
}
7070

server/src/main/java/com/linecorp/centraldogma/server/internal/api/HttpApiExceptionHandler.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@
4848
import com.linecorp.centraldogma.common.RepositoryExistsException;
4949
import com.linecorp.centraldogma.common.RepositoryNotFoundException;
5050
import com.linecorp.centraldogma.common.RevisionNotFoundException;
51+
import com.linecorp.centraldogma.common.TextPatchConflictException;
5152
import com.linecorp.centraldogma.common.TooManyRequestsException;
52-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
53+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
5354
import com.linecorp.centraldogma.server.internal.storage.RequestAlreadyTimedOutException;
5455
import com.linecorp.centraldogma.server.internal.storage.repository.RepositoryMetadataException;
5556
import com.linecorp.centraldogma.server.metadata.MemberNotFoundException;
@@ -90,7 +91,9 @@ public final class HttpApiExceptionHandler implements ServerErrorHandler {
9091
.put(RepositoryExistsException.class,
9192
(ctx, cause) -> newResponse(ctx, HttpStatus.CONFLICT, cause,
9293
"Repository '%s' exists already.", cause.getMessage()))
93-
.put(JsonPatchException.class,
94+
.put(JsonPatchConflictException.class,
95+
(ctx, cause) -> newResponse(ctx, HttpStatus.CONFLICT, cause))
96+
.put(TextPatchConflictException.class,
9497
(ctx, cause) -> newResponse(ctx, HttpStatus.CONFLICT, cause))
9598
.put(RepositoryMetadataException.class,
9699
(ctx, cause) -> newResponse(ctx, HttpStatus.INTERNAL_SERVER_ERROR, cause))

server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/DefaultChangesApplier.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
import com.linecorp.centraldogma.common.Change;
4444
import com.linecorp.centraldogma.common.ChangeConflictException;
4545
import com.linecorp.centraldogma.common.Revision;
46-
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchException;
46+
import com.linecorp.centraldogma.common.TextPatchConflictException;
47+
import com.linecorp.centraldogma.common.jsonpatch.JsonPatchConflictException;
4748
import com.linecorp.centraldogma.internal.Jackson;
4849
import com.linecorp.centraldogma.internal.Util;
4950
import com.linecorp.centraldogma.internal.jsonpatch.JsonPatch;
@@ -159,7 +160,11 @@ int doApply(Revision unused, DirCache dirCache,
159160
try {
160161
newJsonNode = JsonPatch.fromJson((JsonNode) change.content()).apply(oldJsonNode);
161162
} catch (Exception e) {
162-
throw new JsonPatchException("failed to apply JSON patch: " + change, e);
163+
if (e instanceof JsonPatchConflictException) {
164+
throw (JsonPatchConflictException) e;
165+
} else {
166+
throw new JsonPatchConflictException("failed to apply JSON patch: " + change, e);
167+
}
163168
}
164169

165170
// Apply only when the contents are really different.
@@ -196,7 +201,11 @@ int doApply(Revision unused, DirCache dirCache,
196201
newText = joiner.toString();
197202
}
198203
} catch (Exception e) {
199-
throw new ChangeConflictException("failed to apply text patch: " + change, e);
204+
String message = "failed to apply text patch: " + change;
205+
if (e.getMessage() != null) {
206+
message += " (reason: " + e.getMessage() + ')';
207+
}
208+
throw new TextPatchConflictException(message, e);
200209
}
201210

202211
// Apply only when the contents are really different.

0 commit comments

Comments
 (0)