이 가이드에서는 Data Manager API가 오류를 처리하고 전달하는 방법을 설명합니다. API 오류의 구조와 의미를 이해하는 것은 잘못된 입력부터 일시적인 서비스 사용 불가능에 이르기까지 문제를 원활하게 처리할 수 있는 강력한 애플리케이션을 빌드하는 데 매우 중요합니다.
Data Manager API는 gRPC 상태 코드를 기반으로 하는 표준 Google API 오류 모델을 따릅니다. 오류가 발생하는 각 API 응답에는 다음이 포함된 Status 객체가 포함됩니다.
- 숫자 오류 코드
- 오류 메시지
- 추가 오류 세부정보(선택사항)
표준 오류 코드
Data Manager API는 표준 오류 코드 집합을 gRPC 및 HTTP에서 정의한 대로 사용합니다. 이러한 코드는 오류 유형을 대략적으로 나타냅니다. 문제의 근본적인 특성 을 이해하려면 항상 이 코드를 먼저 확인해야 합니다.
이러한 코드에 관한 자세한 내용은 API 디자인 가이드 - 오류 코드를 참고하세요.
오류 처리
요청이 실패하면 다음 단계를 따르세요.
오류 코드를 확인하여 오류 유형을 찾습니다.
오류 코드의 표준 세부정보 페이로드를 확인합니다. 표준 세부정보 페이로드는 Google API의 오류에 대한 메시지 집합 입니다. 표준 세부정보 페이로드는 오류 세부정보를 구조화되고 일관된 방식으로 제공합니다. Data Manager API의 각 오류에는 여러 표준 세부정보 페이로드 메시지가 있을 수 있습니다. Data Manager API 클라이언트 라이브러리 에는 오류에서 표준 세부정보 페이로드를 가져오는 도우미 메서드가 있습니다.
오류 코드와 관계없이
ErrorInfo,RequestInfo,Help, 및LocalizedMessage페이로드를 확인하고 로깅하는 것이 좋습니다.ErrorInfo에는 다른 페이로드에 없을 수 있는 정보가 있습니다.RequestInfo에는 지원팀에 문의해야 하는 경우에 유용한 요청 ID가 있습니다.Help및LocalizedMessage에는 오류를 해결하는 데 도움이 되는 링크와 기타 세부정보가 포함되어 있습니다.
또한
BadRequest페이로드는 오류를 일으킨 필드에 관한 정보를 제공하므로INVALID_ARGUMENT오류에 유용합니다.
표준 세부정보 페이로드
Data Manager API의 가장 일반적인 표준 세부정보 페이로드는 다음과 같습니다.
BadRequest
요청이
INVALID_ARGUMENT (HTTP 상태 코드 400)로 실패하면 BadRequest 페이로드를 확인하세요.
BadRequest 메시지는 요청에 잘못된 값이 있는 필드가 있거나 필수 필드의 값이 누락되었음을 나타냅니다. 오류가 있는 필드를 찾으려면
BadRequest의 field_violations 목록을 확인하세요. 각 field_violations 항목
에는 오류를 해결하는 데 도움이 되는 정보가 있습니다.
field카멜 케이스 경로 구문을 사용하여 요청에서 필드의 위치를 지정합니다.
경로가 목록의 항목 (
repeated필드)을 가리키는 경우 목록 이름 뒤에 대괄호 ([...])로 색인이 표시됩니다.예를 들어
destinations[0].operating_account.account_id는account_id목록의 첫 번째 항목의operating_account에 있는destinations입니다.description값이 오류를 일으킨 이유에 대한 설명입니다.
reasonErrorReasonenum(예:INVALID_HEX_ENCODING또는INVALID_CURRENCY_CODE)
BadRequest 예
다음은 INVALID_ARGUMENT 오류에 대한 샘플 응답이며, BadRequest
메시지가 포함되어 있습니다. The field_violations는 오류가 숫자가 아닌 accountId임을 보여줍니다. field 값 destinations[0].login_account.account_id는 필드 위반이 있는
accountId가 첫 번째 항목
의 login_account에 destinations 목록에 있음을 보여줍니다.
{
"error": {
"code": 400,
"message": "There was a problem with the request.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "INVALID_ARGUMENT",
"domain": "datamanager.googleapis.com",
"metadata": {
"requestId": "t-a8896317-069f-4198-afed-182a3872a660"
}
},
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-a8896317-069f-4198-afed-182a3872a660"
},
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "destinations[0].login_account.account_id",
"description": "String is not a valid number.",
"reason": "INVALID_NUMBER_FORMAT"
}
]
}
]
}
}
다음은 INVALID_ARGUMENT 오류의 또 다른 샘플 응답입니다.
BadRequest 메시지. 이 경우 field_violations 목록에 두 가지
오류가 표시됩니다.
첫 번째
event에는 이벤트의 두 번째 사용자 식별자에 16진수로 인코딩되지 않은 값이 있습니다.두 번째
event에는 이벤트의 세 번째 사용자 식별자에 16진수로 인코딩되지 않은 값이 있습니다.
{
"error": {
"code": 400,
"message": "There was a problem with the request.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "INVALID_ARGUMENT",
"domain": "datamanager.googleapis.com",
"metadata": {
"requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
}
},
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
},
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "events.events[0].user_data.user_identifiers[1]",
"description": "The HEX encoded value is malformed.",
"reason": "INVALID_HEX_ENCODING"
},
{
"field": "events.events[1].user_data.user_identifiers[2]",
"description": "The HEX encoded value is malformed.",
"reason": "INVALID_HEX_ENCODING"
}
]
}
]
}
}
RequestInfo
요청이 실패할 때마다 RequestInfo 페이로드를 확인하세요. RequestInfo
에는 API 요청을 고유하게 식별하는 request_id가 포함되어 있습니다.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
오류를 로깅하거나 지원팀에 문의할 때는 문제 진단에 도움이 되도록 요청 ID를 포함해야 합니다.
ErrorInfo
ErrorInfo 메시지를 확인하여 다른 표준 세부정보 페이로드에 캡처되지 않을 수 있는 추가 정보를 가져옵니다. ErrorInfo
페이로드에는 오류에 관한 정보가 포함된 metadata 맵이 포함되어 있습니다.
예를 들어 Data Manager API가 사용 설정되지 않은 Google Cloud 프로젝트의 사용자 인증 정보를 사용하여 발생한 PERMISSION_DENIED 실패의 ErrorInfo는 다음과 같습니다. ErrorInfo는 다음과 같은 오류에 관한 추가 정보를 제공합니다.
metadata.consumer아래의 요청과 연결된 프로젝트metadata.serviceTitle아래의 서비스 이름metadata.activationUrl아래의 서비스를 사용 설정할 수 있는 URL
{
"error": {
"code": 403,
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "SERVICE_DISABLED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/PROJECT_NUMBER",
"service": "datamanager.googleapis.com",
"containerInfo": "PROJECT_NUMBER",
"serviceTitle": "Data Manager API",
"activationUrl": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
},
...
]
}
}
Help 및 LocalizedMessage
Help 및 LocalizedMessage 페이로드를 확인하여 오류를 이해하고 해결하는 데 도움이 되는
문서 링크와 현지화된 오류 메시지를 가져옵니다.
예를 들어 Data Manager API가 사용 설정되지 않은 Google Cloud 프로젝트의 사용자 인증 정보를 사용하여 발생한 PERMISSION_DENIED
실패의 Help 및 LocalizedMessage는 다음과 같습니다. Help 페이로드에는 서비스
를 사용 설정할 수 있는 URL이 표시되고 LocalizedMessage에는 오류에 관한 설명이 있습니다.
{
"error": {
"code": 403,
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.LocalizedMessage",
"locale": "en-US",
"message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
},
{
"@type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google API Console API activation",
"url": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
}
]
},
...
]
}
}
액세스 오류 세부정보
클라이언트 라이브러리 중 하나를 사용하는 경우 도우미 메서드를 사용하여 표준 세부정보 페이로드를 가져옵니다.
.NET
try {
// Send API request
}
catch (Grpc.Core.RpcException rpcException)
{
Console.WriteLine($"Exception encountered: {rpcException.Message}");
var statusDetails =
Google.Api.Gax.Grpc.RpcExceptionExtensions.GetAllStatusDetails(
rpcException
);
foreach (var detail in statusDetails)
{
if (detail is Google.Rpc.BadRequest)
{
Google.Rpc.BadRequest badRequest = (Google.Rpc.BadRequest)detail;
foreach (
BadRequest.Types.FieldViolation? fieldViolation in badRequest.FieldViolations
)
{
// Access attributes such as fieldViolation!.Reason and fieldViolation!.Field
}
}
else if (detail is Google.Rpc.RequestInfo)
{
Google.Rpc.RequestInfo requestInfo = (Google.Rpc.RequestInfo)detail;
string requestId = requestInfo.RequestId;
// Log the requestId...
}
else if (detail is Google.Rpc.ErrorInfo)
{
Google.Rpc.ErrorInfo errorInfo = (Google.Rpc.ErrorInfo)detail;
// Log the errorInfo.Reason and errorInfo.Metadata...
// Log the details in the 'Metadata' map...
foreach (
KeyValuePair<String, String> metadataEntry in errorInfo.Metadata
)
{
// Log the metadataEntry.Key and metadataEntry.Value...
}
}
else
{
// ...
}
}
}
자바
try {
// Send API request
} catch (com.google.api.gax.rpc.InvalidArgumentException invalidArgumentException) {
// Gets the standard BadRequest payload from the exception.
BadRequest badRequest = invalidArgumentException.getErrorDetails().getBadRequest();
for (int i = 0; i < badRequest.getFieldViolationsCount(); i++) {
FieldViolation fieldViolation = badRequest.getFieldViolations(i);
// Access attributes such as fieldViolation.getField() and fieldViolation.getReason()
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
if (requestInfo != null) {
String requestId = requestInfo.getRequestId();
// Log the requestId...
}
} catch (com.google.api.gax.rpc.ApiException apiException) {
// Fallback exception handler for other types of ApiException.
// Gets the standard ErrorInfo payload from the exception.
ErrorInfo errorInfo = apiException.getErrorDetails().getErrorInfo();
// Log the 'reason' and 'domain'...
// Log the details in the 'metadata' map...
for (Entry<String, String> metadataEntry : errorInfo.getMetadataMap().entrySet()) {
// Log the metadataEntry key and value...
}
// Gets the standard RequestInfo payload from the exception.
RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
if (requestInfo != null) {
String requestId = requestInfo.getRequestId();
// Log the requestId...
}
...
}
오류 처리 권장사항
복원력이 뛰어난 애플리케이션을 빌드하려면 다음 권장사항을 구현하세요.
- 오류 세부정보 검사
- 항상 표준 세부정보
페이로드 중 하나를 찾으세요(예:
BadRequest). 각 표준 세부정보 페이로드에는 오류의 원인을 이해하는 데 도움이 되는 정보가 포함되어 있습니다. 오류. - 클라이언트 오류와 서버 오류 구분
오류가 구현 문제 (클라이언트)로 인해 발생했는지 아니면 API 문제 (서버)로 인해 발생했는지 확인합니다.
- 클라이언트 오류:
INVALID_ARGUMENT,NOT_FOUND,PERMISSION_DENIED,FAILED_PRECONDITION,UNAUTHENTICATED와 같은 코드입니다. 이러한 오류에는 요청 또는 애플리케이션의 상태/사용자 인증 정보를 변경해야 합니다. 문제를 해결하지 않고 요청을 재시도하지 마세요. - 서버 오류:
UNAVAILABLE,INTERNAL,DEADLINE_EXCEEDED,UNKNOWN과 같은 코드입니다. 이러한 오류는 API 서비스의 일시적인 문제를 나타냅니다.
- 클라이언트 오류:
- 재시도 전략 구현
오류를 재시도할 수 있는지 확인하고 재시도 전략을 사용합니다.
UNAVAILABLE,DEADLINE_EXCEEDED,INTERNAL,UNKNOWN,ABORTED와 같은 일시적인 서버 오류에 만 재시도합니다.- 지수 백오프 알고리즘을 사용하여 재시도 간 대기 시간을 늘립니다. 이렇게 하면 이미 스트레스를 받고 있는 서비스에 과부하가 걸리지 않도록 할 수 있습니다. 예를 들어 1초, 2초, 4초 동안 기다린 후 최대 재시도 횟수 또는 총 대기 시간까지 계속 기다립니다.
- 많은 클라이언트가 동시에 재시도하는 'thundering herd' 문제를 방지하기 위해 백오프 지연에 작은 임의의 '지터'를 추가합니다.
- 철저하게 로깅
모든 표준 세부정보 페이로드, 특히 요청 ID를 포함한 전체 오류 응답을 로깅합니다. 이 정보는 디버깅 및 필요한 경우 Google 지원팀에 문제를 신고하는 데 필수적입니다.
- 사용자 의견 제공
표준 세부정보 페이로드의 코드와 메시지를 기반으로 애플리케이션 사용자에게 명확하고 유용한 의견을 제공합니다. 예를 들어 "오류가 발생했습니다"라고만 말하는 대신 "거래 ID가 누락되었습니다" 또는 "대상 계정 ID를 찾을 수 없습니다"라고 말할 수 있습니다.
이 가이드라인을 따르면 Data Manager API에서 반환된 오류를 효과적으로 진단하고 처리하여 더 안정적이고 사용자 친화적인 애플리케이션을 만들 수 있습니다.