palantir / conjure-java-runtime-api Goto Github PK
View Code? Open in Web Editor NEWThe API components of the http-remoting RPC library
License: Apache License 2.0
The API components of the http-remoting RPC library
License: Apache License 2.0
I recently got this error message:
java.lang.AssertionError: Expected unsafe args to be {extra=[extra], missing=[missing_secret, missing_secret2]}, but found {extra=[extra], missing=[missing_secret, missing_secret_2]}
which is confusing because it looks like expected and actual are the same. Actually, their types are different -- one is a String "[extra]"
and one is a Set ImmutableSet.of("extra")
.
In the case where two objects are different, but their toStrings() are equal, we should additionally show in the error message the types of the two objects.
This would happen here:
Minimal repo:
assertThatServiceExceptionThrownBy(() -> {
throw new ServiceException(ErrorType.INTERNAL, UnsafeArg.of("list", ImmutableList.of("a")));
})
.hasArgs(UnsafeArg.of("list", "[a]"));
currently gives message:
java.lang.AssertionError: Expected unsafe args to be {list=[a]}, but found {list=[a]}
Should return a message like:
java.lang.AssertionError: Expected unsafe args to be {list=[a]} with value type String, but found {list=[a]} with value type ImmutableList<String>
According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412, there is already a "Precondition Failed" HTTP error code.
We're currently classifying FAILED_PRECONDITION as 500.
TBH I realize we're probably going for different semantics than conditional requests which is what 412 serves, however it sounds like it should still belong in the 4xx somehow, since it's semantically closer to INVALID_ARGUMENT (400) than to ILLEGAL_STATE (which doesn't exist but I'd map to 500).
If my understanding is incorrect, I'd love for someone to clarify the reasoning behind this.
https://github.com/openzipkin/b3-propagation#debug-flag-1
I would like a way to configure a service to use the JVM's default proxy selector. Currently if ProxyConfiguration#type = HTTP
, it bypasses the system settings. It looks like ProxyConfiguration#type = MESH
uses the default selector, but it seems wrong to configure that.
What are your thoughts on either:
type = DEFAULT
hostAndPort
to System.getenv("http_proxy")
if not set for type = HTTP
I have an arg that's a long, dynamically computed string (a stacktrace). I'd like to confirm that it contains a certain substring, with a syntax like:
assertThatServiceExceptionThrownBy(() -> throwIt())
.hasType(MyErrors.MY_ERROR)
.hasArgSatisfying(arg -> {
assertThat(arg.getName()).isEqualTo("my-arg");
assertThat(arg.getValue()).asString().contains("my-substring");
});
or maybe like this:
assertThatServiceExceptionThrownBy(() -> throwIt())
.hasType(MyErrors.MY_ERROR)
.hasArgWithNameSatisfying("my-arg", value -> assertThat(value).asString().contains("my-substring"));
Right now I'm doing something like this, but would love to improve it:
assertThatServiceExceptionThrownBy(() -> throwIt())
.hasType(MyErrors.MY_ERROR)
.satisfies(serviceException -> assertThat(serviceException.getArgs())
.satisfiesOnlyOnce(arg -> {
assertThat(arg.getName()).isEqualTo("my-arg");
assertThat(arg.getValue()).asString().contains("my-substring");
});
});
https://github.com/palantir/conjure-java-runtime-api/blob/develop/errors/src/main/java/com/palantir/conjure/java/api/errors/RemoteException.java should be in it's own jar - it's only necessary to use when constructing errors from http BODYs. Defining errors, e.g. ErrorType and SerializableError, have nothing to do with http BODY interpretation.
This should help with versioning the client/server parts of error handling independently.
It does not accept single uppercase letter (https://github.com/palantir/http-remoting-api/blob/develop/errors/src/main/java/com/palantir/remoting/api/errors/ErrorType.java#L33), e.g. "Foo:B" will not be a valid error name.
Regexp like ([A-Z]([a-z0-9]+[A-Z])*[a-z0-9]*)
could solve this issue.
The ErrorType.Code
enum is overly restrictive. We only have access to 500 for server errors:
FAILED_PRECONDITION(500),
INTERNAL(500),
TIMEOUT(500),
CUSTOM_SERVER(500);
At a bare minimum, it would be useful to define 501-504.
this is different to a 403
Why does ErrorType.create
throw on CUSTOM_CLIENT
and CUSTOM_SERVER
?
https://github.com/palantir/http-remoting-api/blob/develop/errors/src/main/java/com/palantir/remoting/api/errors/ErrorType.java#L103
It is impossible to extend PartialServiceConfiguration
to support service discovery in cases where more information is required and is provided by the discovered service (for instance, a type
field). This is because the Immutables processor prevents extending from value types. Attempting to do so yields the following error message:
Should not inherit com.palantir.remoting.api.config.service.PartialServiceConfiguration which is a value type itself.
Avoid extending from another abstract value type.
Better to share common abstract class or interface which are not carrying @Immutable annotation.
This shouldn't thrown an NPE if the call to .getValue()
returns null (which can happen if the caller doesn't do something like Strings.nullToEmpty() on all possible values).
Wanted to add a new error code into the list available in ErrorType
: Conflict (409)
Use case is for reporting error when a request wants to open a new transaction when one already exists, as our service does not currently support simultaneous open transactions. I think 409 is the HTTP code that most accurately describes this error.
it would be nice to know the error message thrown when checking the type difference so it's easier to know what went wrong
https://github.com/palantir/conjure-java-runtime-api/blob/develop/test-utils/src/main/java/com/palantir/conjure/java/api/testing/Assertions.java#L54
Serializing a ServiceException
with a non-string object as the value of an Arg
serializes the value of the arg as a JSON string instead of a proper JSON object (seems to happen in SerializableError.forException
where the toString
representation of the object is used, as opposed to the proper JSON object) - for example SafeArg.of("param", ImmutableList.of("arg1", "arg2"))
This is a problem since it's a mismatch between what the consumer of the exception expects (JSON object) and the actual JSON value (JSON string containing the toString
representation of the object)
Convert the safe-arg value to a proper JSON object, since that is what the consumer code expects.
comma logic disregards the possibility of unsafe parameters, when the first parameter is unsafe, the rendered string argument portion takes the form {, arg2=2}
The rendered exception message should only be used by loggers which do not support sls safe logging. In these cases, we should bias towards allowing debugging. Using sls logging unsafeParams are also recorded on disk, so this should not be considered dangerous.
This is a continuation of palantir/safe-logging#76
I'd like to build an SslConfiguration
off the JDK system truststore since I intentionally want to trust certificates from the public CA system. This could be named e.g. SslConfiguration.ofSystemTruststore()
Without this, I have to create a system truststore myself like this (in remoting2 format):
Path trustStorePath = Paths.get(TRUST_STORE_FILE_NAME);
TrustContext trustContext;
if (trustStorePath.toFile().isFile()) {
trustContext = SslSocketFactories.createTrustContext(SslConfiguration.of(trustStorePath));
} else {
// Use the system trustStore
SSLContext defaultSslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = javax.net.ssl.TrustManagerFactory.getInstance("sunX509");
// Initializes with the System KeyStore.
trustManagerFactory.init((KeyStore) null);
trustContext = TrustContext.of(
defaultSslContext.getSocketFactory(),
(X509TrustManager) trustManagerFactory.getTrustManagers()[0]);
}
ClientConfiguration can be created using ServiceConfiguration and there is no easy way to convert PartialServiceConfiguration to ServiceConfiguration or vice versa even though they are pretty much identical except for the absence of security
. I would like know more about how we intend to use the PartialServiceConfiguration class
EDIT: saw ServiceConfigurationFactor.propagateDefaults
and answered my question above.
Other than the retry URL, all messages within QoSExceptions are static. As such it would be nice if they implemented SafeLoggable so that messages were preserved. Alternatively, they could directly extend https://github.com/palantir/safe-logging/blob/develop/preconditions/src/main/java/com/palantir/logsafe/exceptions/SafeRuntimeException.java.
Can we provide human readable time types for weeks and months?
Useful for Foundry Retention.
Something nice to have: aside from the assert classes provided in test-utils, could we add equivalent Hamcrest matchers that works with JUnit's ExpectedException? I imagine it will look like this:
private Matcher<ServiceException> getServiceExceptionMatcher(ErrorType errorTypeToMatch) {
return new BaseMatcher<ServiceException>() {
@Override
public boolean matches(Object item) {
if (!(item instanceof ServiceException)) {
return false;
}
ServiceException castedItem = (ServiceException) item;
return errorTypeToMatch.equals(castedItem.getErrorType());
}
@Override
public void describeMismatch(Object item, Description description) {
if (item instanceof ServiceException) {
description.appendText("was ServiceException with ErrorType ")
.appendValue(((ServiceException) item).getErrorType());
} else {
super.describeMismatch(item, description);
}
}
@Override
public void describeTo(Description description) {
description.appendText("ServiceException with ErrorType ").appendValue(errorTypeToMatch);
}
};
}
Applications often catch and rethrow exceptions, for example, a service may catch RemoteException, and throw a more specific ServiceException with a better ErrorType using the RemoteException as a cause. Today this generates a second errorInstanceId
despite being a continuation of the same error. Debugging the error by looking up the errorInstanceId
becomes an O(n) operation rather than O(1) where a single key provides a veiw of the failure across systems.
The current behavior is perplexing because allowing RemoteExceptions to be reach conjure exception mappers does result in the desired behavior, however in some cases (think failures from an executor) rethrowing the original exception directly makes it harder to trace execution, creating a new exception on the thread calling Future::get
allows us to follow the failure to an endpoint.
ServiceException should traverse causes for an errorInstanceId
before generating a new identifier.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.