PromleeBlog
sitemap
aboutMe

posting thumbnail
에러 라우팅과 파일 변환 전송 - n8n 파이프라인 7편
Error Handling and Fallback Routing - n8n Pipeline Part 7

📅

들어가기 전에 🔗

안녕하세요.
오늘은 뉴스 브리핑 봇 시리즈의 마지막 과정으로 결과물을 메신저로 전송할 때 발생하는 오류를 제어하는 방법을 다룹니다.

LLM이 작성한 텍스트는 내용이 길어질 수 있습니다.
Discord나 Telegram 같은 메신저 API는 1회 전송 가능한 최대 글자 수 제한을 두고 있습니다.
Discord의 경우 2000자를 초과하는 텍스트를 전송하면 서버에서 에러를 반환하며 워크플로우가 중단됩니다.
이러한 상황을 방지하기 위해 텍스트를 파일로 변환하여 대체 전송하는 Fallback 아키텍처를 실습합니다.

1단계 에러 우회 설정과 조건 검사 🔗

일반적인 설정에서는 노드 실행 중 에러가 발생하면 전체 시스템이 멈춥니다.
이를 방지하기 위해
Discord
노드의 에러 처리 방식을 변경해야 합니다.
시작하기 전, 예시 데이터를 만들기 위해
Code
노드를 사용하여 2000자 이상의 긴 텍스트를 생성하는 간단한 스크립트를 작성합니다.
const longText = '글자 수 초과 테스트를 위한 더미 텍스트입니다. '.repeat(1000);
return { json: { output: longText } };

On Error 속성 변경 🔗

첫 번째
Discord
노드의 설정 탭으로 이동하여 On Error 항목을 확인합니다.
이 속성을 에러 출력 선을 사용하는 방식으로 변경합니다.
설정을 적용하면 노드 우측에 에러가 발생했을 때 데이터가 흐르는 별도의 출력 선이 생성됩니다.

If 노드를 통한 에러 검증 🔗

에러 선으로 넘어온 데이터가 실제로 에러인지 확인하기 위해
If
노드를 연결합니다.
조건 설정 창에서 시스템이 반환하는 에러 객체인 JSON 데이터 내의 error 속성이 존재하는지 검사합니다.
Error 속성 판별
Error 속성 판별
이 과정을 통해 에러가 확실히 발생한 경우에만 다음 단계로 넘어가도록 논리 구조를 제어합니다.
Discord 노드 출력 On Error 설정
Discord 노드 출력 On Error 설정
Discord 노드의 출력 선과 If 노드
Discord 노드의 출력 선과 If 노드

2단계 원본 데이터 보존과 분기 처리 🔗

에러가 발생한 지점에서는 원래 보내려던 긴 텍스트 데이터가 훼손되었을 가능성이 있습니다.
따라서 에러 발생 전의 온전한 데이터를 우회하여 가져오는 라우팅 설계가 필요합니다.

Merge 노드를 이용한 데이터 복원 🔗

이 문제를 해결하기 위해
Merge
노드를 활용합니다.
데이터를 생성하는
Code
노드에서 선을 두 갈래로 나누어 하나는 1차 발송 노드로 보내고 다른 하나는
Merge
노드의 두 번째 입력 단자로 보냅니다.

Merge
노드의 작동 방식을 브랜치 선택으로 지정하고 두 번째 입력 데이터를 사용하도록 설정합니다.
이어서
If
노드에서 에러가 확인된 데이터를
Merge
노드의 첫 번째 입력 단자에 연결합니다.
이렇게 결선하면 에러가 발생했다는 신호를 받았을 때 보존해 두었던 원본 데이터를 다시 끌어와 다음 노드로 전달할 수 있습니다.
Merge 노드 설정값
Merge 노드 설정값

3단계 텍스트 파일 변환과 Fallback 전송 🔗

보존된 긴 텍스트 데이터를 파일 형태로 변환하여 메신저 서버의 글자 수 제한을 회피합니다.
Merge
노드 뒤에
Convert to File
노드를 연결합니다.

파일 변환 및 문서 전송 노드 설정 🔗

Convert to File
노드는 전달받은 텍스트 문자열을 텍스트 파일 포맷으로 변환합니다.
변환이 완료된 데이터 뒤에 두 번째
Discord
노드를 배치합니다.

이 노드는 텍스트 전송이 아닌 파일 첨부 방식으로 설정합니다.
메시지 내용에는 내용이 길어 파일을 첨부한다는 안내 문구를 작성합니다.
이 설정을 통해 글자 수가 초과하더라도 시스템 중단 없이 문서 파일 형태로 브리핑을 전달할 수 있습니다.
Convert to File 을 거쳐 두 번째 Discord 노드로 전달
Convert to File 을 거쳐 두 번째 Discord 노드로 전달

4단계 정상 및 에러 상황 비교 실습 🔗

독자분들이 정상 전송과 에러 Fallback 라우팅을 모두 테스트해 볼 수 있도록 구성된 최종 워크플로우를 제공합니다.
아래의 JSON 코드를 복사하여 n8n 화면에 붙여넣기 하시면 전체 노드와 위치가 복원됩니다.
정상 및 에러 상황 테스트용 파이프라인 JSON
{
  "nodes":[
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position":[2032, 1008],
      "id": "a69d1f3a-58b6-4a5d-bc8d-ad1fa9b78c38",
      "name": "Manual Trigger"
    },
    {
      "parameters": {
        "jsCode": "const longText = '글자 수 초과 테스트를 위한 더미 텍스트입니다. '.repeat(1000);\nreturn { json: { output: longText } };"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position":[2240, 1008],
      "id": "6a948f8d-76e4-4bd3-9066-b0db03aae52a",
      "name": "더미 데이터 생성"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "content": "={{ $json.output }}",
        "options": {}
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [2416, 880],
      "id": "7a92094d-d011-4dab-8b0c-107a3ad1ac9d",
      "name": "Discord 1차 발송",
      "alwaysOutputData": false,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "toText",
        "sourceProperty": "output",
        "options": {}
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [2736, 1168],
      "id": "acf65c7c-bbd2-4351-97d2-f46ab4b37768",
      "name": "텍스트 파일 변환"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "content": "내용이 길어져 파일을 첨부합니다.",
        "options": {},
        "files": {
          "values":[
            {
              "inputFieldName": "=data"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position":[2880, 1168],
      "id": "8a37668f-bfe1-45e1-b51a-44c198e6cda7",
      "name": "Discord 폴백 발송"
    },
    {
      "parameters": {
        "mode": "chooseBranch",
        "useDataOfInput": 2
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [2592, 1168],
      "id": "b71e8096-6b6c-4cee-be5f-a89164fb95e8",
      "name": "Merge"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions":[
            {
              "id": "b274de46-201b-4d55-95eb-256118840802",
              "leftValue": "={{ $json.error }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position":[2656, 864],
      "id": "e9f33ccf-bb97-4444-8f42-663883044bca",
      "name": "If"
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [[
          {
            "node": "더미 데이터 생성",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "더미 데이터 생성": {
      "main": [[
          {
            "node": "Discord 1차 발송",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Discord 1차 발송": {
      "main": [[
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ],[]
      ]
    },
    "텍스트 파일 변환": {
      "main":[[
          {
            "node": "Discord 폴백 발송",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [[
          {
            "node": "텍스트 파일 변환",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [[
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
제공된 코드를 그대로 실행하면 2000자가 넘어 의도적으로 에러가 발생하고 파일 변환 프로세스가 작동합니다.
정상적인 전송을 테스트하고 싶다면 두 번째
Code
노드의 자바스크립트 코드에서 .repeat(1000) 부분을 .repeat(1)로 수정한 뒤 실행해 보시기 바랍니다.
글자 수가 제한을 넘지 않으므로 1차 발송 노드에서 전송이 완료되고 이후의 에러 라우팅은 작동하지 않게 됩니다.

결론 🔗

이번 7편을 마지막으로 데이터 수집부터 Multi-Agent 분석 그리고 복잡한 예외 처리까지 아우르는 파이프라인 구축 여정이 마무리되었습니다.
단순히 노드를 연결하는 것을 넘어 트래픽 제한을 고려하고 분기 처리를 설계하는 과정은 실제 백엔드 개발의 핵심 논리와 동일합니다.

이 아키텍처를 응용하여 자신만의 견고한 자동화 시스템을 완성해 보시길 바랍니다.

참고 🔗