BlueTalk 에러 코드 · 응답 포맷 > BlueTalk::블루톡 무료 실시간 채팅 위젯 · 1:1 DM · 웹 채팅 연동

에러 코드
1. 공통 개념

BlueTalk는 성공/실패를 명확하게 구분하기 위해 응답에 공통적으로 ok 값을 사용합니다.

// 성공 응답 (예시)
{
  "ok": true,
  "data": { ... }       // 또는 "file": { ... }, "result": { ... } 등
}

// 실패 응답 (WebSocket 기본 패턴)
{
  "ok": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "사람이 읽을 수 있는 에러 메시지 (선택)"
  }
}

// 실패 응답 (REST 파일 업로드: 간단한 패턴)
{
  "ok": false,
  "reason": "ERROR_CODE"
}
  • ok : true면 성공, false면 실패입니다.
  • error.code / reason : 프로그램에서 분기 처리에 사용하는 에러 코드입니다.
  • error.message : 사용자 또는 운영자가 볼 수 있는 설명(선택)입니다.

WebSocket 이벤트는 기본적으로 { ok, error: { code, message } } 패턴을 사용하며,
REST 파일 업로드(/upload/chat-file)는 현재 구현상 { ok, reason } 형태를 사용합니다.

2. WebSocket 에러 응답 구조

WebSocket 이벤트에서 에러가 발생하면, 서버는 다음과 같은 형태로 응답합니다.

// 예: 채널 메시지 전송 실패
sendAck(cb, {
  ok: false,
  error: { code: 'PARAM_REQUIRED' }
});

// 예: 존재하지 않는 채널
sendAck(cb, {
  ok: false,
  error: { code: 'CHANNEL_NOT_FOUND' }
});

// 예: 내부 서버 에러
sendAck(cb, {
  ok: false,
  error: { code: 'INTERNAL_ERROR' }
});

DM 관련 이벤트에서도 동일한 패턴을 사용합니다.

// 예: DM 대상이 자기 자신일 경우
cb({ ok: false, error: { code: 'CANNOT_SELF' } });

// 예: 세션이 존재하지 않을 때
cb({ ok: false, error: { code: 'SESSION_NOT_FOUND' } });

// 예: 채팅금지 상태에서 전송 시도
cb({ ok: false, error: { code: 'BANNED_CHAT' } });

프론트엔드에서는 if (!res.ok) 체크 후 res.error.code 값으로 분기하여 상황별 안내 메시지나 재시도 버튼 등을 구현할 수 있습니다.

3. REST 에러 응답 구조 (파일 업로드)

POST /upload/chat-file 엔드포인트는 현재 다음과 같은 간단한 에러 포맷을 사용합니다.

// 파일이 누락된 경우
HTTP 400
{ "ok": false, "reason": "FILE_REQUIRED" }

// 사이트 인증 실패 (등록된 site_key/도메인 조합이 아님)
HTTP 400 또는 401
{ "ok": false, "reason": "SITE_NOT_FOUND" }

// 서버 내부 오류
HTTP 500
{ "ok": false, "reason": "INTERNAL_ERROR" }

프론트엔드에서는 response.ok 또는 status를 먼저 확인하고,
JSON.reason 값을 사용해 오류 유형을 판별합니다.

향후 REST API 전반을 { ok, error: { code, message } } 패턴으로 통일할 수 있으며,
현재는 파일 업로드에 한해 reason 필드를 사용하고 있습니다.

4. HTTP Status 코드 매핑 (권장)

REST API에서는 다음과 같은 Status 코드 사용을 권장합니다.

Status 상태 설명 / 예시
200 OK 정상 처리 요청 성공. { ok:true, ... } 응답.
400 Bad Request 잘못된 요청 필수 파라미터 누락(PARAM_REQUIRED), 잘못된 포맷 등이 해당됩니다.
파일 업로드에서 FILE_REQUIRED 등.
401 Unauthorized 인증 실패 사이트 인증 실패(SITE_NOT_FOUND), 토큰/세션 만료(AUTH_REQUIRED) 등.
403 Forbidden 권한 없음 채팅금지(BANNED_CHAT), 채널생성금지(BANNED_CREATE 등) 상황에 권장됩니다.
404 Not Found 리소스 없음 존재하지 않는 채널(CHANNEL_NOT_FOUND), 존재하지 않는 파일/DM 세션(ATTACH_NOT_FOUND, SESSION_NOT_FOUND) 등.
429 Too Many Requests 요청 과다 향후 속도 제한(Rate Limit) 기능 추가 시 사용 권장.
500 Internal Server Error 서버 오류 예측하지 못한 에러.
응답에는 { ok:false, reason:'INTERNAL_ERROR' } 또는 { ok:false, error:{ code:'INTERNAL_ERROR' } } 형태를 권장합니다.

HTTP Status는 큰 분류를, JSON의 code/reason세부 분류를 담당하도록 설계하는 것이 좋습니다.

5. 대표 에러 코드 목록

1) 공통 / 시스템

코드 설명
PARAM_REQUIRED 필수 파라미터가 누락되었거나 값이 비어있는 경우.
INTERNAL_ERROR 예측하지 못한 서버 내부 오류.
LIST_FAILED 목록 조회 중 오류 발생 (DM 리스트 등).

2) 인증 / 사이트

코드 설명
AUTH_FAILED 사이트 측 회원 인증 API(auth_url) 호출 결과 인증 실패.
AUTH_REQUIRED 로그인이 필요하거나 세션이 만료된 상태.
SITE_NOT_FOUND 등록되지 않은 도메인/site_key 조합. (파일 업로드 등)
SESSION_NOT_FOUND DM 세션/채팅 세션을 찾을 수 없을 때.

3) 채널 / 글로벌 채팅

코드 설명
CHANNEL_NOT_FOUND 요청한 채널이 존재하지 않거나, 접근할 수 없는 경우.
EMPTY_MESSAGE 메시지 내용이 없을 때 (공백/trim 후 빈 문자열).
NOT_PARTICIPANT 채널 또는 세션의 참가자가 아닌 사용자가 요청할 때.
NOT_ACTIVE 비활성화된 채널/세션에 접근하려 할 때.

4) DM(1:1 메시지) 관련

코드 설명
TARGET_REQUIRED DM 대상 사용자 정보가 누락된 경우.
CANNOT_SELF 자기 자신에게 DM을 보내려는 경우.
DM_KEY_REQUIRED DM 세션 식별자(dm_key)가 누락된 경우.
NOT_PENDING 대기 상태가 아닌 세션에 대해 승인/거절 등을 시도할 때.
NOT_OWNER 해당 DM 세션의 owner가 아닌 사용자가 owner 권한 작업을 시도할 때.
NOT_TARGET 대상이 아닌 사용자가 target 전용 작업을 시도할 때.
ATTACH_NOT_FOUND DM 첨부파일 정보를 찾을 수 없는 경우.

5) 제재(밴) 관련

코드 설명
BANNED_CHAT 채팅금지 상태에서 메시지를 전송하려 할 때.
BAN_FAILED 채팅금지/제재 설정 중 오류 발생.
BAN_SET_FAILED 제재 설정을 DB에 반영하는 데 실패.
BAN_CLEAR_FAILED 제재 해제 처리 중 오류.

6) 파일 업로드 관련

코드 설명
FILE_REQUIRED 업로드할 파일이 포함되지 않았을 때.
SITE_NOT_FOUND 파일 업로드 시, 등록되지 않은 사이트(site_key)일 때.
INTERNAL_ERROR 업로드 처리 중 예기치 않은 서버 오류.

※ 실제 코드에는 위 외에도 세부 에러 코드가 더 있을 수 있으며,
버전 업 과정에서 추가/변경될 수 있습니다. 공통 패턴(ok + code)만 유지되면 프론트엔드에서는 비교적 쉽게 대응할 수 있습니다.

6. 프론트엔드에서의 처리 팁

간단한 예시 JavaScript 코드를 통해 에러 처리 패턴을 보여드립니다.

// 예: WebSocket 이벤트 콜백
socket.emit('channel:message', payload, (res) => {
  if (!res || !res.ok) {
    const code = res?.error?.code || 'UNKNOWN';
    switch (code) {
      case 'BANNED_CHAT':
        alert('현재 채팅금지 상태입니다. 관리자에게 문의하세요.');
        break;
      case 'CHANNEL_NOT_FOUND':
        alert('채널을 찾을 수 없습니다. 새로고침 후 다시 시도해 주세요.');
        break;
      case 'PARAM_REQUIRED':
        alert('필수 입력 값이 누락되었습니다. 내용을 확인해 주세요.');
        break;
      default:
        alert('처리 중 오류가 발생했습니다. [' + code + ']');
    }
    return;
  }

  // 성공 처리...
  console.log('메시지 전송 성공');
});
// 예: 파일 업로드 (fetch)
async function uploadChatFile(file) {
  const form = new FormData();
  form.append('file', file);
  form.append('site_key',   SITE_KEY);
  form.append('channel_key','global');
  form.append('user_id',    GLOBAL_USER_ID);
  form.append('user_key',   GLOBAL_USER_KEY);

  const rsp  = await fetch('https://server.bluetalk.kr/upload/chat-file', {
    method: 'POST',
    body: form
  });

  const json = await rsp.json();
  if (!json.ok) {
    const reason = json.reason || 'UNKNOWN';
    if (reason === 'FILE_REQUIRED') {
      alert('업로드할 파일을 선택해 주세요.');
    } else if (reason === 'SITE_NOT_FOUND') {
      alert('사이트 인증에 실패했습니다. 관리자에게 문의하세요.');
    } else {
      alert('파일 업로드 중 오류가 발생했습니다. [' + reason + ']');
    }
    return null;
  }

  return json.file;  // { id, type, name, size, mime }
}

에러 처리 로직을 잘 만들어두면, 예상치 못한 상황에서도 사용자 경험(UX)을 안정적으로 유지할 수 있습니다.

팔로팡 오일보이&커스텀 AI코인봇 AI Coin Bot 코스퀀트