All skills
secondsky avatar

/sap-cloud-sdk-ai

@620a19a
by Eddiesecondsky/sap-skills456 stars
120

Integrates SAP Cloud SDK for AI into JavaScript/TypeScript and Java applications. Use when building applications with SAP AI Core, Generative AI Hub, or Orchestration Service. Covers chat completion, embedding, streaming, function calling, content filtering, data masking, document grounding, prompt registry, and LangChain/Spring AI integration. Supports OpenAI GPT-4o, Llama, Gemini, Amazon Nova, and other foundation models via SAP BTP.

Use this Skill: https://skilld.dev/gh/secondsky/sap-skills/sap-cloud-sdk-ai

This session only. Nothing lands on disk.

referenceserror-handling.md

≈2.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Error Handling Guide

Guide for handling errors when using SAP Cloud SDK for AI.

Table of Contents

  1. Overview
  2. JavaScript Error Handling
  3. Java Error Handling
  4. Common Errors
  5. Content Filter Errors
  6. Retry Strategies

Overview

SAP Cloud SDK for AI provides structured error handling with:

  • ErrorWithCause (JS) - Nested error chains with root cause access
  • Exceptions (Java) - Standard Java exception hierarchy
  • Detailed error messages - HTTP status, response body, context

JavaScript Error Handling

ErrorWithCause Pattern

The SDK uses ErrorWithCause to provide detailed error context:

import { OrchestrationClient } from '@sap-ai-sdk/orchestration';

const client = new OrchestrationClient({
  promptTemplating: { model: { name: 'gpt-4o' } }
});

try {
  const response = await client.chatCompletion({
    placeholderValues: { question: 'Hello' }
  });
  console.log(response.getContent());
} catch (error) {
  if (error instanceof Error) {
    // Top-level error message
    console.error('Error:', error.message);

    // Access cause chain
    if ('cause' in error && error.cause instanceof Error) {
      console.error('Caused by:', error.cause.message);

      // HTTP response details
      if ('response' in error.cause) {
        const response = (error.cause as any).response;
        console.error('Status:', response?.status);
        console.error('Data:', response?.data);
      }
    }

    // Root cause
    if ('rootCause' in error) {
      console.error('Root cause:', (error as any).rootCause.message);
    }
  }
}

Error Stack Representation

Error: Chat completion request failed
    at OrchestrationClient.chatCompletion (...)
Caused by: Request to orchestration service failed
    at sendRequest (...)
Caused by: AxiosError: Request failed with status code 401
    at Axios.request (...)

Handling Specific Error Types

import axios from 'axios';

try {
  await client.chatCompletion({ placeholderValues });
} catch (error) {
  // Check for HTTP errors
  if (axios.isAxiosError(error) || error.cause?.code === 'ECONNREFUSED') {
    console.error('Network error - check connectivity');
    return;
  }

  // Check for timeout
  if (error.message?.includes('timeout')) {
    console.error('Request timed out');
    return;
  }

  // Check for auth errors
  if (error.cause?.response?.status === 401) {
    console.error('Authentication failed - check credentials');
    return;
  }

  // Check for rate limiting
  if (error.cause?.response?.status === 429) {
    console.error('Rate limited - retry after delay');
    return;
  }

  throw error;
}

Java Error Handling

Standard Exception Handling

import com.sap.ai.sdk.orchestration.*;

var client = new OrchestrationClient();
var config = new OrchestrationModuleConfig()
    .withLlmConfig(OrchestrationAiModel.GPT_4O);

try {
    var prompt = new OrchestrationPrompt("Hello");
    var result = client.chatCompletion(prompt, config);
    System.out.println(result.getContent());
} catch (OrchestrationException e) {
    System.err.println("Orchestration error: " + e.getMessage());

    // Access HTTP details
    if (e.getCause() != null) {
        System.err.println("Caused by: " + e.getCause().getMessage());
    }
} catch (Exception e) {
    System.err.println("Unexpected error: " + e.getMessage());
    e.printStackTrace();
}

Checking Response Status

try {
    var result = client.chatCompletion(prompt, config);

    // Check for filter violations (output)
    try {
        String content = result.getContent();
    } catch (ContentFilterException e) {
        System.err.println("Output blocked by content filter");
    }
} catch (ContentFilterException e) {
    // Input was blocked
    System.err.println("Input blocked by content filter: " + e.getMessage());
}

Common Errors

Connection Errors

Error Cause Solution
Could not find any matching service bindings for service identifier 'aicore' No AI Core binding Bind service or set AICORE_SERVICE_KEY
ECONNREFUSED AI Core unreachable Check network, VPN, proxy settings
ETIMEDOUT Request timeout Increase timeout, check network
ENOTFOUND DNS resolution failed Verify URL in service key

Authentication Errors

Error Cause Solution
401 Unauthorized Invalid credentials Verify clientid/clientsecret
401 - Token expired OAuth token expired SDK should auto-refresh; check token URL
403 Forbidden Insufficient permissions Check service plan, roles

Deployment Errors

Error Cause Solution
Orchestration deployment not found No deployment Use 'default' group or deploy orchestration
404 Not Found Invalid deployment ID Verify deployment exists
Model not available Model not deployed Check available models in AI Launchpad

Request Errors

Error Cause Solution
400 Bad Request Invalid request body Check prompt format, parameters
413 Payload Too Large Input too long Reduce input size
422 Unprocessable Entity Schema validation failed Fix request structure
429 Too Many Requests Rate limited Implement backoff, reduce frequency
500 Internal Server Error Server-side issue Retry, contact SAP support

Token Limit Errors

// Handle token limit errors
try {
  await client.chatCompletion({ placeholderValues });
} catch (error) {
  if (error.message?.includes('context_length_exceeded')) {
    console.error('Input too long - reduce context or use summarization');
  }
  if (error.message?.includes('max_tokens')) {
    console.error('Increase max_tokens parameter or expect truncated response');
  }
}

Content Filter Errors

Input Filter Violation (JavaScript)

import { buildAzureContentSafetyFilter } from '@sap-ai-sdk/orchestration';

const client = new OrchestrationClient({
  promptTemplating: { model: { name: 'gpt-4o' } },
  filtering: {
    input: buildAzureContentSafetyFilter({ Hate: 'ALLOW_SAFE' })
  }
});

try {
  await client.chatCompletion({
    placeholderValues: { question: 'potentially harmful content' }
  });
} catch (error) {
  if (error.message?.includes('content filter') ||
      error.message?.includes('ContentFilterViolation')) {
    console.error('Input blocked by content filter');
    // Handle gracefully - request user to rephrase
  }
}

Output Filter Violation (JavaScript)

const response = await client.chatCompletion({ placeholderValues });

try {
  const content = response.getContent();
} catch (error) {
  if (error.message?.includes('content filter')) {
    console.error('Model output was blocked');
    // May need to adjust filter thresholds or prompt
  }
}

Java Content Filter Handling

try {
    var result = client.chatCompletion(prompt, config);
    var content = result.getContent(); // May throw if output filtered
} catch (ContentFilterException e) {
    System.err.println("Content filter violation");
    System.err.println("Category: " + e.getCategory());
    System.err.println("Severity: " + e.getSeverity());
}

Filter Categories

Category Description
Hate Hateful or discriminatory content
SelfHarm Self-harm related content
Sexual Sexual content
Violence Violent content

Filter Severity Levels

Level Threshold Constant
Safe only ALLOW_SAFE
Safe + Low ALLOW_SAFE_LOW
Safe + Low + Medium ALLOW_SAFE_LOW_MEDIUM
All (no filtering) ALLOW_ALL

Retry Strategies

JavaScript - LangChain Retry

LangChain clients have built-in retry:

import { OrchestrationClient } from '@sap-ai-sdk/langchain';

const client = new OrchestrationClient(config, {
  maxRetries: 3 // Default is 6
});

Note: Content filter errors do NOT trigger retry.

JavaScript - Manual Retry

async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries: number = 3,
  baseDelay: number = 1000
): Promise<T> {
  let lastError: Error | undefined;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error as Error;

      // Don't retry client errors (4xx except 429)
      const status = (error as any).cause?.response?.status;
      if (status >= 400 && status < 500 && status !== 429) {
        throw error;
      }

      // Exponential backoff
      const delay = baseDelay * Math.pow(2, attempt);
      console.log(`Retry ${attempt + 1}/${maxRetries} after ${delay}ms`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }

  throw lastError;
}

// Usage
const response = await withRetry(() =>
  client.chatCompletion({ placeholderValues })
);

Java - Resilience4j

import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryConfig;

var retryConfig = RetryConfig.custom()
    .maxAttempts(3)
    .waitDuration(Duration.ofSeconds(1))
    .exponentialBackoff(2, Duration.ofSeconds(10))
    .retryOnException(e ->
        !(e instanceof ContentFilterException) &&
        !(e instanceof IllegalArgumentException)
    )
    .build();

var retry = Retry.of("aicore", retryConfig);

var result = Retry.decorateSupplier(retry, () ->
    client.chatCompletion(prompt, config)
).get();

Rate Limit Handling

async function handleRateLimit<T>(fn: () => Promise<T>): Promise<T> {
  try {
    return await fn();
  } catch (error) {
    const status = (error as any).cause?.response?.status;
    const retryAfter = (error as any).cause?.response?.headers?.['retry-after'];

    if (status === 429) {
      const delay = retryAfter ? parseInt(retryAfter) * 1000 : 60000;
      console.log(`Rate limited. Waiting ${delay}ms`);
      await new Promise(resolve => setTimeout(resolve, delay));
      return fn(); // Retry once after waiting
    }

    throw error;
  }
}

Best Practices

  1. Always wrap SDK calls in try-catch - Errors can occur at any layer
  2. Log error chains - Use error.cause to get full context
  3. Handle content filters gracefully - Don't expose raw filter errors to users
  4. Implement retry with backoff - For transient errors (5xx, 429)
  5. Don't retry client errors - 4xx errors (except 429) indicate request problems
  6. Set appropriate timeouts - Prevent hanging requests
  7. Monitor error rates - Track patterns to identify systemic issues

Documentation Links

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive documentation and integration guide for the SAP Cloud SDK for AI. It follows security best practices for credential management, emphasizing environment variables and service bindings over hardcoded secrets. It also provides extensive guidance on implementing security controls like content filtering and data masking to mitigate risks inherent in AI integrations.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    8/12 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 620a19a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "maintainer": "Eduard Jiglau",
  "maintainer_email": "hello@sap-ai-skills.com",
  "website": "https://sap-ai-skills.com",
  "version": "2.4.1",
  "last_verified": "2026-06-15",
  "package_evidence": "docs/project/package-evidence/2026-06-15.json"
}

README badge

README badge for secondsky/sap-skills/sap-cloud-sdk-ai