한 줄 요약: 반환된 그대로의 원시 응답 본문을 정확히 출력하십시오. 프로그램이 감싸서 만든 한 줄 문자열만 보관하지 마십시오.
400 Bad Request 같은 문자열은 진단에 거의 도움이 되지 않습니다. 실제 답은 버려진 JSON 안에 있습니다.실제 사례: 400 Bad Request는 아무것도 알려주지 않습니다
한 고객이 딱 한 줄만 보고했습니다:400은 보통 콘텐츠 안전성 문제이거나 파라미터 문제입니다. 가장 가능성이 높은 것은 콘텐츠 안전성입니다.그것은 추측이지 결론이 아닙니다. 왜냐하면 바로 그 동일한 호출에 대해 실제 응답 본문은 다음 셋 중 하나였을 수 있고, 각각은 완전히 다른 조치를 요구하기 때문입니다:
백엔드 로그에 있는 것과 없는 것
먼저 바로잡아야 할 정신 모델은 다음과 같습니다: 백엔드 로그는 오류 로그가 아니라 과금 원장입니다.반드시 유지해야 하는 7개 필드
이것은 실패한 호출 하나를 진단하는 데 필요한 모든 정보입니다. 이 중 하나라도 빠지면 진단은 다시 추측 수준으로 떨어집니다:응답 본문을 잘라내지 마십시오. 200자로 자르는 것은 일반적인 업무 로그에서는 괜찮지만, 진단용으로는 유용한 세부 정보가 끝부분에 있는 경우가 많습니다. 적어도 앞의 2000자는 유지하십시오. 이미지 엔드포인트에서 base64가 로그를 가득 채울까 걱정된다면,
status_code >= 400일 때만 전체 본문을 출력하십시오 — 오류 본문은 어차피 짧습니다.오류 포착 패턴을 올바르게 처리하기
사실 원칙은 하나뿐입니다. 두 계층에서 모두 잡고, 어느 계층에서도 아무것도 버리지 않는 것입니다.- 전송 계층 실패: 연결 재설정, TLS 핸드셰이크 실패, 타임아웃, DNS 실패입니다. HTTP 응답은 전혀 없으며, 예외 텍스트만 받을 수 있습니다.
- HTTP 계층 오류: 서버가 4xx / 5xx를 반환했습니다. 응답 본문이 있으므로, 반드시 읽어야 합니다.
Python / requests
Python / OpenAI SDK
공식 SDK는 이미 예외 객체에 세 가지 정보를 모두 붙여 줍니다. 대부분의 사람들은 대신 자신의 한 줄짜리 메시지를print합니다.
Node.js
SDK를 사용할 때는:fetch를 사용할 때는, 대부분 여기서 잘못됩니다:
cURL로 재현하기
누군가에게 문제 재현을 요청할 때 이 명령은 가장 적은 수고로 충분합니다. 상태 코드, 헤더, 본문, 시간 정보를 한 번에 보여 줍니다.-i는 응답 헤더를 출력하며,x-request-id가 있는 곳이 바로 그곳입니다.-sS는 진행 표시줄을 숨기지만 오류 출력은 유지합니다.-w는 상태 코드와 전체 시간을 덧붙여 주며, 타임아웃 설정과 비교할 때 유용합니다.
래퍼와 사내 게이트웨이
좋은 예시
이 오류는 한 고객의 ComfyUI 노드에서 발생했습니다:400 Bad Request보다 훨씬 더 지저분하지만 — 그럼에도 완전하므로, 방향은 몇 초 만에 결정됩니다:
결론은 바로 나옵니다. 이것은 콘텐츠 안전성이나 매개변수와 무관한 전송 계층 문제이며, 과금도 발생하지 않습니다(요청이 끝까지 완료되지 않았기 때문입니다). 문제 해결 경로: Image API 연결 끊김.
두 경우를 비교해 보십시오: 하나는 보기 좋게 포장되어 있지만 아무것도 설명하지 못하고(
400 Bad Request), 다른 하나는 길고 지저분하지만 원인을 바로 가리킵니다(errno 10054). 진단에서는 친절하고 깔끔하게 다시 쓴 오류보다, 원시적이고 지저분하지만 완전한 오류가 언제나 더 낫습니다.일반 도구에서 원시 출력을 찾는 위치
사내 게이트웨이를 위한 세 가지 규칙
1
그대로 통과시키고, 절대 다시 쓰지 마십시오
중간 계층은 문맥(어떤 서비스인지, 어떤 테넌트인지, 몇 번째 재시도인지)을 추가할 수는 있지만, 상위
error.message를 대체해서는 안 됩니다. 한 번 다시 쓰면 원문을 복구할 두 번째 장소가 없어집니다.2
사용자에게 보이는 메시지를 원시 메시지와 별도로 저장하십시오
Gemini 이미지 오류 처리에서 사용하는 세 부분 구조를 따르십시오:
userMessage(최종 사용자용 친절한 문구), devMessage(개발자용 분류), rawResponse(수정하지 않은 응답 본문)입니다. 앞의 두 개는 마음껏 다듬고, 세 번째는 그대로 저장하십시오.3
알 수 없는 오류를 절대 내보내지 마십시오
폴백 분기에서는
status, x-request-id 및 본문의 처음 2000자를 기록하십시오. 원문 텍스트를 담고 있는 “분류되지 않은 오류”는 진단할 수 있지만, 깔끔한 “알 수 없는 오류”는 그렇지 않습니다.진단을 불가능하게 만드는 안티패턴
except Exception as e: print("request failed")— 예외 객체가 사라져서 어떤 계층이 실패했는지도 알 수 없습니다;- 상태 코드는 기록하지만 본문은 기록하지 않기 — 이 페이지 맨 위에 있는 바로 그 경우입니다;
raise_for_status()을resp.text를 먼저 읽지 않고 호출하기 — 메시지는 여전히 메모리에 있지만, 아직 조회되지 않았을 뿐입니다;fetch에서if (!resp.ok) throw new Error(resp.statusText)하기 — 본문이 응답 객체와 함께 버려집니다;- 성공한 재시도 후 깨끗한 200만 남겨두기 — 각 시도를 별도로 기록하십시오, 그렇지 않으면 전송이 몇 번 실패했는지 보이지 않고, 자신의 재시도를 게이트웨이 동작으로 착각할 수 있습니다;
- stdout에만 기록하거나, 덮어쓰기로 매일 순환하기 — 고객이 문제를 보고할 때쯤이면 원본 기록은 대개 이미 지나가 버립니다;
- 화면의 휴대전화 사진으로 문제를 보고하기 — 대신 텍스트를 붙여넣으십시오; 스크린샷은 오류의 한 줄을 절반쯤 잘라내는 경우가 자주 있습니다.
지원에 문의해야 하는 경우
먼저 위의 캡처 및 해석 단계를 진행하십시오. 다음 중 어느 하나라도 해당하면 자료를 지원팀에 전달하십시오.- 전체 응답 본문이 있고
error.message가 업스트림을 가리키는 경우(upstream_error, 원시 업스트림 5xx, 또는 명시적인 채널 오류) - 동일한 요청 매개변수가 다른 모델에서는 동작하거나 다른 시점에는 동작하지만, 특정한 한 모델에서만 일관되게 실패하는 경우
- 오류가
500+write_response_body_failed또는 이와 유사한 다운스트림 전달 실패이며, 일관되게 재현되는 경우입니다(이 경우 과금되지 않습니다. 연결 끊김을 참조하십시오) - 과금이 실제 호출과 일치하지 않는다고 의심되는 경우 — 정확히 맞아떨어지는 유일한 기준은
request_id입니다
지원 티켓 템플릿(복사하여 붙여넣기)
WeCom 지원

@apiyi001로 문의하시거나 [email protected]로 이메일을 보내실 수 있습니다.관련 문서
API 매뉴얼
공통 오류 코드, 인증 및 요청 제한
연결 끊김
ECONNRESET, errno 10054 및 SSL EOF에 대한 전체 문제 해결 절차로그 조회 API
API를 통해 호출 로그를 가져오는 방법 —
request_id를 조회하고 과금을 대조하는 방법과금 금액 확인
실패한 호출이 왜 로그에 기록되지 않는지, 그리고 이를 진단 테스트로 사용하는 방법
타임아웃 설정
모델 유형별 타임아웃 단계와, 늘려도 도움이 되지 않을 때 확인할 사항
이미지 API 핵심 사항
동기 호출, base64 접두사 차이,
400 invalid_image_file 전처리