Skip to content

Commit 76a0e04

Browse files
author
Henry Harris
committed
add BaseServiceException
1 parent 45c7d47 commit 76a0e04

File tree

3 files changed

+107
-92
lines changed

3 files changed

+107
-92
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://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,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.palantir.conjure.java.api.errors;
18+
19+
import com.palantir.logsafe.Arg;
20+
import java.util.List;
21+
import javax.annotation.Nullable;
22+
23+
public abstract class BaseServiceException extends RuntimeException {
24+
25+
protected final ErrorType errorType;
26+
27+
protected final List<Arg<?>> args; // unmodifiable
28+
29+
protected final String errorInstanceId;
30+
31+
protected final String unsafeMessage;
32+
protected final String noArgsMessage;
33+
34+
/**
35+
* Creates a new exception for the given error. All {@link com.palantir.logsafe.Arg parameters} are propagated to
36+
* clients; they are serialized via {@link Object#toString}.
37+
*/
38+
BaseServiceException(ErrorType errorType, Arg<?>... parameters) {
39+
this(errorType, null, parameters);
40+
}
41+
42+
/**
43+
* As above, but additionally records the cause of this exception.
44+
*/
45+
BaseServiceException(ErrorType errorType, @Nullable Throwable cause, Arg<?>... args) {
46+
// TODO(rfink): Memoize formatting?
47+
super(cause);
48+
49+
this.errorType = errorType;
50+
this.errorInstanceId = ServiceExceptionUtils.generateErrorInstanceId(cause);
51+
52+
// Note that instantiators cannot mutate List<> args since it comes through copyToList in all code paths.
53+
this.args = ServiceExceptionUtils.arrayToUnmodifiableList(args);
54+
55+
this.unsafeMessage = ServiceExceptionUtils.renderUnsafeMessage(exceptionName(), errorType, args);
56+
this.noArgsMessage = ServiceExceptionUtils.renderNoArgsMessage(exceptionName(), errorType);
57+
}
58+
59+
/**
60+
* The name of the exception. Typically, the class name.
61+
*/
62+
protected abstract String exceptionName();
63+
64+
/**
65+
* The {@link ErrorType} that gave rise to this exception.
66+
*/
67+
public ErrorType getErrorType() {
68+
return errorType;
69+
}
70+
71+
/**
72+
* A unique identifier for (this instance of) this error.
73+
*/
74+
public String getErrorInstanceId() {
75+
return errorInstanceId;
76+
}
77+
78+
@Override
79+
public String getMessage() {
80+
// Including all args here since any logger not configured with safe-logging will log this message.
81+
return unsafeMessage;
82+
}
83+
84+
public String getLogMessage() {
85+
// Not returning safe args here since the safe-logging framework will log this message + args explicitly.
86+
return noArgsMessage;
87+
}
88+
89+
public List<Arg<?>> getArgs() {
90+
return args;
91+
}
92+
}

errors/src/main/java/com/palantir/conjure/java/api/errors/EndpointServiceException.java

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,65 +18,26 @@
1818

1919
import com.palantir.logsafe.Arg;
2020
import com.palantir.logsafe.SafeLoggable;
21-
import java.util.List;
2221
import javax.annotation.Nullable;
2322

2423
/*
2524
* This is identical to ServiceException, but is used in Conjure-generated code to indicate that an exception was thrown
2625
* from a service endpoint.
2726
*/
28-
public abstract class EndpointServiceException extends RuntimeException implements SafeLoggable {
27+
public class EndpointServiceException extends BaseServiceException implements SafeLoggable {
28+
2929
private static final String EXCEPTION_NAME = "EndpointServiceException";
30-
private final ErrorType errorType;
31-
private final List<Arg<?>> args; // This is an unmodifiable list.
32-
private final String errorInstanceId;
33-
private final String unsafeMessage;
34-
private final String noArgsMessage;
3530

36-
/**
37-
* Creates a new exception for the given error. All {@link com.palantir.logsafe.Arg parameters} are propagated to
38-
* clients.
39-
*/
4031
public EndpointServiceException(ErrorType errorType, Arg<?>... parameters) {
41-
this(errorType, null, parameters);
32+
super(errorType, parameters);
4233
}
4334

44-
/** As above, but additionally records the cause of this exception. */
4535
public EndpointServiceException(ErrorType errorType, @Nullable Throwable cause, Arg<?>... args) {
46-
super(cause);
47-
this.errorInstanceId = ServiceExceptionUtils.generateErrorInstanceId(cause);
48-
this.errorType = errorType;
49-
this.args = ServiceExceptionUtils.arrayToUnmodifiableList(args);
50-
this.unsafeMessage = ServiceExceptionUtils.renderUnsafeMessage(EXCEPTION_NAME, errorType, args);
51-
this.noArgsMessage = ServiceExceptionUtils.renderNoArgsMessage(EXCEPTION_NAME, errorType);
52-
}
53-
54-
/** The {@link ErrorType} that gave rise to this exception. */
55-
public final ErrorType getErrorType() {
56-
return errorType;
57-
}
58-
59-
/** A unique identifier for (this instance of) this error. */
60-
public final String getErrorInstanceId() {
61-
return errorInstanceId;
62-
}
63-
64-
/** A string that includes the exception name, error type, and all arguments irrespective of log-safety. */
65-
@Override
66-
public final String getMessage() {
67-
// Including all args here since any logger not configured with safe-logging will log this message.
68-
return unsafeMessage;
69-
}
70-
71-
/** A string that includes the exception name and error type, without any arguments. */
72-
@Override
73-
public final String getLogMessage() {
74-
return noArgsMessage;
36+
super(errorType, cause, args);
7537
}
7638

77-
/** The list of arguments. */
7839
@Override
79-
public final List<Arg<?>> getArgs() {
80-
return args;
40+
protected String exceptionName() {
41+
return EXCEPTION_NAME;
8142
}
8243
}

errors/src/main/java/com/palantir/conjure/java/api/errors/ServiceException.java

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,62 +21,24 @@
2121
import java.util.List;
2222
import javax.annotation.Nullable;
2323

24-
/** A {@link ServiceException} thrown in server-side code to indicate server-side {@link ErrorType error states}. */
25-
public final class ServiceException extends RuntimeException implements SafeLoggable {
26-
private static final String EXCEPTION_NAME = "ServiceException";
27-
private final ErrorType errorType;
28-
private final List<Arg<?>> args; // unmodifiable
24+
/**
25+
* A {@link ServiceException} thrown in server-side code to indicate server-side {@link ErrorType error states}.
26+
*/
27+
public final class ServiceException extends BaseServiceException implements SafeLoggable {
2928

30-
private final String errorInstanceId;
31-
private final String unsafeMessage;
32-
private final String noArgsMessage;
29+
private static final String EXCEPTION_NAME = "ServiceException";
3330

34-
/**
35-
* Creates a new exception for the given error. All {@link com.palantir.logsafe.Arg parameters} are propagated to
36-
* clients; they are serialized via {@link Object#toString}.
37-
*/
3831
public ServiceException(ErrorType errorType, Arg<?>... parameters) {
39-
this(errorType, null, parameters);
32+
super(errorType, parameters);
4033
}
4134

42-
/** As above, but additionally records the cause of this exception. */
4335
public ServiceException(ErrorType errorType, @Nullable Throwable cause, Arg<?>... args) {
44-
// TODO(rfink): Memoize formatting?
45-
super(cause);
46-
47-
this.errorInstanceId = ServiceExceptionUtils.generateErrorInstanceId(cause);
48-
this.errorType = errorType;
49-
// Note that instantiators cannot mutate List<> args since it comes through copyToList in all code paths.
50-
this.args = ServiceExceptionUtils.arrayToUnmodifiableList(args);
51-
this.unsafeMessage = ServiceExceptionUtils.renderUnsafeMessage(EXCEPTION_NAME, errorType, args);
52-
this.noArgsMessage = ServiceExceptionUtils.renderNoArgsMessage(EXCEPTION_NAME, errorType);
53-
}
54-
55-
/** The {@link ErrorType} that gave rise to this exception. */
56-
public ErrorType getErrorType() {
57-
return errorType;
58-
}
59-
60-
/** A unique identifier for (this instance of) this error. */
61-
public String getErrorInstanceId() {
62-
return errorInstanceId;
63-
}
64-
65-
@Override
66-
public String getMessage() {
67-
// Including all args here since any logger not configured with safe-logging will log this message.
68-
return unsafeMessage;
69-
}
70-
71-
@Override
72-
public String getLogMessage() {
73-
// Not returning safe args here since the safe-logging framework will log this message + args explicitly.
74-
return noArgsMessage;
36+
super(errorType, cause, args);
7537
}
7638

7739
@Override
78-
public List<Arg<?>> getArgs() {
79-
return args;
40+
protected String exceptionName() {
41+
return EXCEPTION_NAME;
8042
}
8143

8244
/**

0 commit comments

Comments
 (0)