Skip to content

Commit fe71a07

Browse files
committed
Update exception handling in demo
- move handling to controller - update docs/signature to tag throwing methods
1 parent 9a2029b commit fe71a07

File tree

3 files changed

+22
-28
lines changed

3 files changed

+22
-28
lines changed

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import com.fasterxml.jackson.databind.ObjectMapper;
99
import com.sap.ai.sdk.app.services.OrchestrationService;
1010
import com.sap.ai.sdk.orchestration.AzureFilterThreshold;
11+
import com.sap.ai.sdk.orchestration.OrchestrationClientException;
1112
import com.sap.ai.sdk.orchestration.model.DPIEntities;
1213
import com.sap.cloud.sdk.cloudplatform.thread.ThreadContextExecutors;
14+
import java.util.Map;
1315
import javax.annotation.Nonnull;
1416
import lombok.extern.slf4j.Slf4j;
1517
import org.springframework.beans.factory.annotation.Autowired;
@@ -161,21 +163,31 @@ ResponseEntity<String> inputFiltering(
161163
* @return a {@link ResponseEntity} containing the filtered output. The response is either in JSON
162164
* format if the "accept" header specifies "application/json" or in plain content format
163165
* otherwise.
166+
* @throws OrchestrationClientException if the output filter filtered the LLM response.
164167
* @throws JsonProcessingException if an error occurs while converting the response to JSON.
165168
*/
166169
@GetMapping("/outputFiltering/{policy}")
167170
@Nonnull
168171
ResponseEntity<String> outputFiltering(
169172
@RequestHeader(value = "accept", required = false) final String accept,
170173
@Nonnull @PathVariable("policy") final AzureFilterThreshold policy)
171-
throws JsonProcessingException {
172-
final var response = service.outputFiltering(policy);
174+
throws JsonProcessingException, OrchestrationClientException {
175+
176+
String content;
177+
try {
178+
content = service.outputFiltering(policy).getContent();
179+
} catch (OrchestrationClientException e) {
180+
content = "Failed to obtain a response as the content was flagged by output filter.";
181+
log.debug(content, e);
182+
}
183+
173184
if ("application/json".equals(accept)) {
174185
return ResponseEntity.ok()
175186
.contentType(MediaType.APPLICATION_JSON)
176-
.body(mapper.writeValueAsString(response));
187+
.body(mapper.writeValueAsString(Map.of("content", content)));
177188
}
178-
return ResponseEntity.ok(response.getContent());
189+
190+
return ResponseEntity.ok(content);
179191
}
180192

181193
/**

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,26 +93,21 @@ public OrchestrationChatResponse messagesHistory(@Nonnull final String prevMessa
9393
* @link <a
9494
* href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/input-filtering">SAP
9595
* AI Core: Orchestration - Input Filtering</a>
96+
* @throws OrchestrationClientException if input filter filters the prompt
9697
* @param policy the explicitness of content that should be allowed through the filter
9798
* @return the assistant response object
9899
*/
99100
@Nonnull
100-
public OrchestrationChatResponse inputFiltering(@Nonnull final AzureFilterThreshold policy) {
101+
public OrchestrationChatResponse inputFiltering(@Nonnull final AzureFilterThreshold policy)
102+
throws OrchestrationClientException {
101103
final var prompt =
102104
new OrchestrationPrompt("'We shall spill blood tonight', said the operation in-charge.");
103105
final var filterConfig =
104106
new AzureContentFilter().hate(policy).selfHarm(policy).sexual(policy).violence(policy);
105107

106108
final var configWithFilter = config.withInputFiltering(filterConfig);
107109

108-
try {
109-
return client.chatCompletion(prompt, configWithFilter);
110-
} catch (OrchestrationClientException e) {
111-
if (e.getMessage().contains("400 Bad Request")) {
112-
log.info("Content filtered out by input filter before any response was available.");
113-
}
114-
throw e;
115-
}
110+
return client.chatCompletion(prompt, configWithFilter);
116111
}
117112

118113
/**
@@ -137,20 +132,7 @@ public OrchestrationChatResponse outputFiltering(@Nonnull final AzureFilterThres
137132
new AzureContentFilter().hate(policy).selfHarm(policy).sexual(policy).violence(policy);
138133

139134
final var configWithFilter = config.withOutputFiltering(filterConfig);
140-
final var response = client.chatCompletion(prompt, configWithFilter);
141-
142-
try {
143-
response.getContent();
144-
} catch (OrchestrationClientException e) {
145-
if (e.getMessage().contains("filtered the output")) {
146-
log.info(
147-
"Content filtered out by output filter but the LLM instead responded: '{}'",
148-
response.getChoice().getMessage().getContent());
149-
}
150-
throw e;
151-
}
152-
153-
return response;
135+
return client.chatCompletion(prompt, configWithFilter);
154136
}
155137

156138
/**

sample-code/spring-app/src/test/java/com/sap/ai/sdk/app/controllers/OrchestrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ void testInputFilteringLenient() {
210210
void testOutputFilteringStrict() {
211211
var policy = AzureFilterThreshold.ALLOW_SAFE;
212212

213-
assertThatThrownBy(() -> service.outputFiltering(policy))
213+
assertThatThrownBy(() -> service.outputFiltering(policy).getContent())
214214
.isInstanceOf(OrchestrationClientException.class)
215215
.hasMessageContaining("Content filter filtered the output.");
216216
}

0 commit comments

Comments
 (0)