Skip to content
10 changes: 7 additions & 3 deletions client/build.gradle
Comment thread
nytian marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ compileTestJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
options.fork = true
options.forkOptions.executable = "${PATH_TO_TEST_JAVA_RUNTIME}/bin/javac"
def javacName = org.gradle.internal.os.OperatingSystem.current().isWindows() ? 'javac.exe' : 'javac'
options.forkOptions.executable = "${PATH_TO_TEST_JAVA_RUNTIME}/bin/${javacName}"
}

task downloadProtoFiles {
Expand Down Expand Up @@ -93,7 +94,9 @@ protobuf {
}
generateProtoTasks {
all()*.plugins { grpc {} }
all()*.dependsOn downloadProtoFiles
if (project.gradle.startParameter.taskNames.any { it.contains('downloadProtoFiles') }) {
all()*.dependsOn downloadProtoFiles
}
}
}

Expand All @@ -110,7 +113,8 @@ sourceSets {
}

tasks.withType(Test) {
executable = new File("${PATH_TO_TEST_JAVA_RUNTIME}", 'bin/java')
def javaName = org.gradle.internal.os.OperatingSystem.current().isWindows() ? 'java.exe' : 'java'
executable = new File("${PATH_TO_TEST_JAVA_RUNTIME}", "bin/${javaName}")
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
private final DataConverter dataConverter;
private final Duration maximumTimerInterval;
private final DurableTaskGrpcWorkerVersioningOptions versioningOptions;
private final ExceptionPropertiesProvider exceptionPropertiesProvider;

private final TaskHubSidecarServiceBlockingStub sidecarClient;

Expand Down Expand Up @@ -70,6 +71,7 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
this.dataConverter = builder.dataConverter != null ? builder.dataConverter : new JacksonDataConverter();
this.maximumTimerInterval = builder.maximumTimerInterval != null ? builder.maximumTimerInterval : DEFAULT_MAXIMUM_TIMER_INTERVAL;
this.versioningOptions = builder.versioningOptions;
this.exceptionPropertiesProvider = builder.exceptionPropertiesProvider;
}

/**
Expand Down Expand Up @@ -123,7 +125,8 @@ public void startAndBlock() {
this.dataConverter,
this.maximumTimerInterval,
logger,
this.versioningOptions);
this.versioningOptions,
this.exceptionPropertiesProvider);
TaskActivityExecutor taskActivityExecutor = new TaskActivityExecutor(
this.activityFactories,
this.dataConverter,
Expand Down Expand Up @@ -351,11 +354,9 @@ public void startAndBlock() {
activityRequest.getTaskId());
} catch (Throwable e) {
activityError = e;
failureDetails = TaskFailureDetails.newBuilder()
.setErrorType(e.getClass().getName())
.setErrorMessage(e.getMessage())
.setStackTrace(StringValue.of(FailureDetails.getFullStackTrace(e)))
.build();
Exception ex = e instanceof Exception ? (Exception) e : new RuntimeException(e);
Comment thread
nytian marked this conversation as resolved.
Outdated
failureDetails = FailureDetails.fromException(
ex, this.exceptionPropertiesProvider).toProto();
} finally {
activityScope.close();
TracingHelper.endSpan(activitySpan, activityError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public final class DurableTaskGrpcWorkerBuilder {
DataConverter dataConverter;
Duration maximumTimerInterval;
DurableTaskGrpcWorkerVersioningOptions versioningOptions;
ExceptionPropertiesProvider exceptionPropertiesProvider;

/**
* Adds an orchestration factory to be used by the constructed {@link DurableTaskGrpcWorker}.
Expand Down Expand Up @@ -125,6 +126,21 @@ public DurableTaskGrpcWorkerBuilder useVersioning(DurableTaskGrpcWorkerVersionin
return this;
}

/**
* Sets the {@link ExceptionPropertiesProvider} to use for extracting custom properties from exceptions.
* <p>
* When set, the provider is invoked whenever an activity or orchestration fails with an exception. The returned
* properties are included in the {@link FailureDetails} and can be retrieved via
* {@link FailureDetails#getProperties()}.
*
* @param provider the exception properties provider
* @return this builder object
*/
public DurableTaskGrpcWorkerBuilder exceptionPropertiesProvider(ExceptionPropertiesProvider provider) {
this.exceptionPropertiesProvider = provider;
return this;
}

/**
* Initializes a new {@link DurableTaskGrpcWorker} object with the settings specified in the current builder object.
* @return a new {@link DurableTaskGrpcWorker} object
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.microsoft.durabletask;

import javax.annotation.Nullable;
import java.util.Map;

/**
* Provider interface for extracting custom properties from exceptions.
* <p>
* Implementations of this interface can be registered with a {@link DurableTaskGrpcWorkerBuilder} to include
* custom exception properties in {@link FailureDetails} when activities or orchestrations fail.
* These properties are then available via {@link FailureDetails#getProperties()}.
* <p>
* Example usage:
* <pre>{@code
* DurableTaskGrpcWorker worker = new DurableTaskGrpcWorkerBuilder()
* .exceptionPropertiesProvider(exception -> {
* if (exception instanceof MyCustomException) {
* MyCustomException custom = (MyCustomException) exception;
* Map<String, Object> props = new HashMap<>();
* props.put("errorCode", custom.getErrorCode());
* props.put("retryable", custom.isRetryable());
* return props;
* }
* return null;
* })
* .addOrchestration(...)
* .build();
* }</pre>
*/
@FunctionalInterface
public interface ExceptionPropertiesProvider {

/**
* Extracts custom properties from the given exception.
* <p>
* Return {@code null} or an empty map if no custom properties should be included for this exception.
*
* @param exception the exception to extract properties from
* @return a map of property names to values, or {@code null}
*/
@Nullable
Map<String, Object> getExceptionProperties(Exception exception);
}
Loading
Loading