오류와 성능 저하 처리하기

오류와 성능 저하 처리하기

거부된 요청과 수락되었지만 나중에 실패한 연산을 구분해 봐요. 이렇게 하면 재시도가 잘못된 입력을 숨기거나 작업을 중복하지 않아요.

출처: 문서

본문

SDK는 타입 있는 요청 오류와 대기 오류를 노출해요. 명령의 0이 아닌 종료 코드는 세 번째 결과예요. SDK는 실패한 명령을 성공적으로 관찰할 수 있어요.

실패 분류하기

메시지 텍스트가 아니라 오류 타입과 구조화된 코드를 사용하세요. 예시는 흔한 요청 실패를 그룹화하고 호출자에게 그 세부 정보를 보존해요.

  • 잘못된 인자는 수정된 요청이 필요해요.
  • 인증 실패는 유효한 자격 증명이 필요하고, 권한 실패는 적절한 계정 접근이 필요해요.
  • 잘못된 상태 오류는 재시도 전에 상태 확인이 필요해요.
  • 용량이나 할당량 거부는 대기하거나 사용량을 줄이는 것이 필요할 수 있어요.
  • 일시적 가용성 실패는 연산을 안전하게 반복할 수 있다면 재시도 가능할 수 있어요.

대기 오류는 대기가 멈추기 전에 관찰된 상태나 리소스를 보존해요. 그 정보를 검사하고 필요하면 리소스를 다시 읽어요. 실패한 생성, 중단된 대기, 만료된 클라이언트 마감은 같은 정리 결과를 갖지 않아요.

프로세스 헬퍼는 샌드박스 자격 증명을 얻는 중이거나 프로세스가 시작된 후 출력을 읽는 중에 실패할 수 있어요. 오류는 수락된 프로세스와 그 원인을 보존해요. 그 프로세스는 여전히 실행 중일 수 있어요. 명령 재시도 여부를 결정하기 전에 그것을 검사하세요. 원인 체인에서 타입 있는 자격 증명 서비스 속도 제한 오류를 검사하세요. 서비스가 제공한 요청 ID와 재시도 지연을 포함해서요.

예시에서 알 수 없는 오류는 알 수 없는 채로 남아요. 응답이 오기 전의 연결 실패일 수 있어요. 쓰기가 수락되지 않았다고 가정하지 마세요.

자격 증명과 시크릿을 담은 요청 본문을 진단에서 제외하세요. 대신 리소스 이름, 오류 코드, 요청 ID를 기록하세요. 변형(mutation)을 반복하기 전에 안전한 재시도 문서를 참고하세요.

핵심 코드:

if (!(error instanceof RequestError)) {
  return { kind: 'other', code: undefined, details: [] };
}
const { code, details } = error.raw;
const known = KINDS.get(code);
return { kind: known ?? 'other', code, details: details ?? [] };

완전한 TypeScript 예시: failures/classify.ts

import { RequestError, ResourceWaitError } from '@docker/sandboxes';

type Status = RequestError['raw'];
type Detail = NonNullable<Status['details']>[number];

export type FailureKind =
  | 'invalid-request'
  | 'not-served'
  | 'wrong-state'
  | 'exhausted'
  | 'access-or-missing'
  | 'unavailable'
  | 'other';

export interface Failure {
  kind: FailureKind;
  code: string | undefined;
  details: Detail[];
}

const KINDS = new Map<string, FailureKind>([
  ['invalidArgument', 'invalid-request'],
  ['unimplemented', 'not-served'],
  ['failedPrecondition', 'wrong-state'],
  ['resourceExhausted', 'exhausted'],
  ['unauthenticated', 'access-or-missing'],
  ['permissionDenied', 'access-or-missing'],
  ['notFound', 'access-or-missing'],
  ['unavailable', 'unavailable'],
]);

export function readFailure(error: unknown): Failure {
  if (!(error instanceof RequestError)) {
    return { kind: 'other', code: undefined, details: [] };
  }
  const { code, details } = error.raw;
  const known = KINDS.get(code);
  return { kind: known ?? 'other', code, details: details ?? [] };
}

export function readSandboxWait(
  error: unknown,
): 'degraded' | 'failed' | 'other' {
  if (error instanceof ResourceWaitError) {
    if (error.kind === 'interrupted' && error.state === 'degraded')
      return 'degraded';
    if (error.kind === 'failure' && error.state === 'failed')
      return 'failed';
  }
  return 'other';
}

더 알아보기 (Learn more)