본문으로 건너뛰기
취준생을 위한 n8n 실전 워크플로우 레시피 · 38/44시리즈 보기 →

실패해도 안 죽는 슬랙 알림 — n8n의 재시도(retryOnFail)와 에러 분기(continueErrorOutput)

· 약 7분
Datapopcorn CEO / AI automation educator
이 글과 연결된 글 보기
7편 · 20개 연결
100%
매일 아침 7시 날씨를 디스코드로 받는 n8n 날씨 알림 — 시트 대신 외부 API를 읽는 첫 워크플로우n8n Data Table 처음 써보기 — 트렌드 3개를 합쳐 매일 아침 분석 주제 뽑는 워크플로우n8n으로 정적 웹서버 운영하기 — 수료증 발급부터 진위 확인까지, 멱등 처리로 안전하게벡터DB 없이 실시간으로 사이트를 읽는 챗봇 — 경복대학교 안내 챗봇 해부실패해도 안 죽는 슬랙 알림 — n8n의 재시도(retryOnFail)와 에러 분기(continueErrorOutput)구글시트에 쌓인 데이터를 인스타그램 카드뉴스로 — n8n 시트 인스타그램 자동발행서브워크플로우를 Tool로 감싸 AI Agent에게 서버 점검시키기 — 그리고 시스템 프롬프트만으로는 부족한 이유

드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.

표시된 글 7편 목록
전체 글 연결 탐색

이전 편에서 만든 날씨 알림은 매일 아침 조용히 돌긴 하지만, OpenWeatherMap 서버가 잠깐 응답하지 않는 순간이 언젠가 옵니다. 그 순간 워크플로우가 어떻게 반응하는지가 이번 편의 전부입니다. 노드에 재시도(retryOnFail)를 걸어 두면 잠깐의 지연은 사람이 모르는 사이 흡수되고, 그래도 안 되면 에러 분기(continueErrorOutput)가 "성공적으로 실패했다"는 사실 자체를 슬랙으로 알려줍니다.

이 워크플로우 하나로 보여줄 수 있는 것​

지금 Datapopcorn n8n 클라우드에서 실제로 운영 중인(active) 워크플로우입니다. 노드 5개짜리라 작아 보이지만, 안에 들어간 역량은 "API를 부른다"가 아니라 "API가 실패했을 때 무엇을 하는가"입니다.

  • 재시도(retryOnFail) — 일시적인 네트워크 지연이나 API 타임아웃을 사람이 알아채기도 전에 흡수하는 설정
  • 에러 분기(continueErrorOutput) — 재시도까지 다 실패했을 때 워크플로우 전체를 멈추는 대신, 실패 사실만 골라 다른 경로로 흘려보내는 구조
  • 안전한 에러 메시지 접근 — 에러 객체의 모양이 매번 같지 않다는 전제로, 옵셔널 체이닝과 널 병합으로 방어적인 표현식을 쓰는 습관

이 세 가지는 OpenWeatherMap뿐 아니라 HTTP Request로 부르는 모든 외부 API에 그대로 옮겨 씁니다.

배경 — 언젠가는 API가 응답하지 않습니다​

이전 편을 만들 때는 "일단 돌아가는 것"이 목표였습니다. 하지만 매일 아침 6시에 자동으로 도는 워크플로우는 사람이 지켜보지 않는 시간에 실행됩니다. OpenWeatherMap이 잠깐 느려지거나, 서버 쪽 문제로 5xx를 돌려주거나, 네트워크가 한 번 끊기는 순간이 언젠가 옵니다. 기본값(stopWorkflow)으로 두면 그 순간 워크플로우는 그냥 멈추고, 아무도 모릅니다. 다음 날 "왜 어제 알림이 안 왔지"라고 묻는 사람이 첫 신호입니다.

이 워크플로우는 그 순간에 대비해 두 가지를 미리 걸어 뒀습니다. OpenWeatherMap 노드가 실패하면 먼저 재시도부터 하고, 그래도 안 되면 실패했다는 사실 자체를 같은 채널로 보냅니다. 설치나 OpenWeatherMap 기본 사용법은 이전 편에서 다뤘으니 이 글에서는 반복하지 않습니다.

구조 — Trigger / Task / Target​

  • Trigger — 매일 06:00 스케줄
  • Task — 날씨 조회를 최대 3회 재시도 → 성공/실패로 갈라지기
  • Target — 같은 슬랙 채널로 정상 메시지 또는 실패 알림 중 하나

트리거 하나, 조회 노드 하나, 그 뒤로 슬랙 노드 두 개가 성공·실패 갈래로 나뉘는 구조입니다.

만들기​

1. OpenWeatherMap 노드에 재시도 걸기​

노드 설정 패널의 Settings 탭에서 Retry On Fail을 켜면 Max Tries와 Wait Between Tries가 나타납니다. 이 워크플로우는 Max Tries 3회, Wait Between Tries 5000ms(5초)로 되어 있습니다.

n8n의 재시도 엔진은 시도 횟수를 최대 5회, 대기시간을 최대 5초까지만 허용합니다. 이 설정은 대기시간은 상한인 5초를 그대로 쓰고, 횟수는 상한(5회)보다 적은 3회로 잡았습니다. 3회 × 5초면 최악의 경우에도 15초 정도만 더 기다리고 다음 단계로 넘어가는 선에서 끝납니다. 재시도를 상한치인 5회까지 밀어붙이면 실패 알림이 그만큼 늦게 도착할 뿐 아니라, 매일 같은 시각에 도는 다른 자동화와 겹쳐 무료 API 플랜의 분당 호출 제한에 더 가까이 다가가게 됩니다. 3회는 "잠깐의 지연은 흡수하되 오래 붙잡고 있지는 않는다"는 절충점입니다.

2. On Error를 에러 출력으로 바꾸기​

Settings 탭 아래쪽의 On Error 드롭다운을 기본값 Stop Workflow에서 Continue (using error output)로 바꾸면, 노드에 출력이 하나 더 생깁니다. 캔버스에서 노드 오른쪽에 초록 점(정상 출력)과 빨간 점(에러 출력) 두 개가 보이면 제대로 바뀐 것입니다.

이 설정만으로는 아무 일도 일어나지 않습니다. 에러 출력을 실제로 뒤 노드에 연결해야 그 경로로 데이터가 흐릅니다. 둘 중 하나만 해두면 — 즉 On Error는 바꿨는데 에러 출력에 아무것도 안 붙여두면 — 재시도까지 다 실패한 데이터는 어디로도 가지 않고 조용히 버려집니다. 실행 로그에는 에러가 안 뜨고, 화면만 보면 워크플로우가 정상 종료된 것처럼 보이는 조용한 실패 모드입니다. 이 워크플로우의 connections를 보면 조회 노드의 출력이 정상 메시지 노드와 실패 알림 노드 둘 다에 연결되어 있어서, 이 두 단계가 세트로 되어 있는 걸 확인할 수 있습니다.

여기서 만드는 건 워크플로우 전체를 감시하는 안전망이 아니라, 노드 하나가 실패했을 때만 반응하는 국소적 방어입니다. 이전 편 한계 섹션에서 "실패하면 조용히 멈춥니다"라고 적어 두고 넘겼던 부분이 바로 이 지점인데, 거기서 예고했던 건 워크플로우 전체가 죽었을 때 별도 워크플로우를 실행해 잡아주는 Error Trigger 쪽 패턴이었습니다. 이 편에서 쓴 continueErrorOutput은 그보다 작은 단위입니다. 조회 노드 하나가 실패해도 워크플로우 자체는 안 죽고, 그 노드의 에러만 별도 경로로 흘려보낼 뿐입니다. 워크플로우 전체가 알 수 없는 이유로 죽는 경우까지 잡으려면 Error Trigger가 따로 필요하고, 두 패턴은 겹치지 않고 보완합니다.

3. 정상 메시지 노드 — 재시도는 있지만 에러 분기는 없습니다​

정상 갈래의 슬랙 메시지 노드(Send Weather to Slack)에도 Retry On Fail이 똑같이 걸려 있습니다. 슬랙 API 호출도 실패할 수 있으니 여기도 재시도로 흡수하는 게 맞습니다. 다만 이 노드는 On Error가 기본값 그대로입니다. 재시도까지 다 실패하면 워크플로우가 멈춥니다.

이건 빈틈이라기보다 합리적인 선택입니다. 실패 알림도 같은 슬랙 채널로 보내는 구조라, 슬랙 자체가 응답하지 않는 상황이면 실패 알림도 똑같이 실패합니다. 조회 노드에만 에러 분기를 두고 메시지 발송 노드에는 안 둔 건, "무엇이 실패했을 때 알려줄 가치가 있는가"를 구분한 결과로 읽을 수 있습니다.

4. 실패 알림 노드 — 안전한 에러 메시지 접근​

실패 알림 노드(Send Failure Alert)의 메시지 본문에는 이런 표현식이 들어 있습니다.

⚠️ 오늘 아침 날씨 조회 실패 ({{ $now.toFormat("yyyy-MM-dd HH:mm") }})
에러: {{ $json.error?.message ?? "unknown" }}
실행 로그를 확인해주세요.

$json.error?.message ?? "unknown"에는 두 연산자가 붙어 있습니다. ?.(옵셔널 체이닝)은 $json.error가 없어도 그 아래의 .message를 읽으려다 에러를 던지지 않고 undefined로 넘어가게 해줍니다. ??(널 병합)는 왼쪽 값이 null이나 undefined일 때만 오른쪽의 "unknown"을 채웁니다.

이 조합이 필요한 이유는 에러 출력으로 넘어오는 데이터의 모양이 실패 유형마다 조금씩 다를 수 있어서입니다. $json.error.message처럼 옵셔널 체이닝 없이 바로 접근하면, 어느 실패 케이스에서 그 경로가 없을 때 이 표현식 자체가 에러를 던지고, 실패를 알리려던 노드가 되레 실패해 아무 메시지도 안 가는 역설이 생깁니다. 실패를 보고하는 노드는 그 실패보다 더 튼튼하게 짜야 합니다.

원본 캔버스에 남아 있는 것​

이 워크플로우는 스티키 노트 하나가 붙어 있습니다. 목적과 실패 시 동작("3회 재시도 후 같은 채널로 실패 알림 발송")을 적은 뒤, 마지막 줄에 이렇게 경고해 둔 게 있습니다. 06시라는 트리거 시각은 워크플로우 Settings의 Timezone 값을 따르니 Asia/Seoul로 되어 있는지 확인하라는 내용입니다. 재시도 로직을 아무리 잘 짜도 트리거 자체가 다른 시간대로 도는 워크플로우는 매일 엉뚱한 시각에 실패하는 것보다 더 눈에 안 띄는 문제라, 만든 사람이 일부러 남겨 둔 메모로 보입니다.

한계​

  • 긴 장애에는 못 버팁니다 — 재시도 3회에 5초 간격이면 총 대기 시간은 15초 안팎입니다. OpenWeatherMap이 몇 분 이상 응답하지 않으면 재시도로도 못 버티고 실패 알림 경로로 넘어갑니다. 이건 의도된 동작이지 버그가 아닙니다.
  • 실패 알림 자체가 실패할 수 있습니다 — 앞서 본 것처럼 실패 알림 노드는 자신의 재시도를 갖고 있지 않고, 같은 슬랙 채널을 씁니다. 슬랙 쪽 장애와 OpenWeatherMap 장애가 겹치면 둘 다 조용해집니다.
  • 워크플로우 전체가 죽는 경우는 못 잡습니다 — continueErrorOutput은 이 조회 노드 하나에만 걸려 있는 국소적 방어입니다. 워크플로우 어딘가 다른 곳에서 예상 못 한 크래시가 나면 이 경로는 작동하지 않고, 그건 Error Trigger의 영역입니다.

포트폴리오·면접 포인트​

포트폴리오에는 On Error 드롭다운을 바꾸는 화면과, 조회 노드를 일부러 실패시켜(예를 들어 API 키를 잠깐 지워서) 실패 알림이 실제로 슬랙에 도착하는 캡처 두 장이 좋습니다. 후자가 있으면 "설정만 켰다"가 아니라 "직접 실패시켜서 확인했다"는 걸 보여줄 수 있습니다.

면접에서는 "재시도 횟수를 어떻게 정했나요?" 같은 질문이 올 수 있습니다. 무조건 많이 돌리는 게 안전해 보이지만, 재시도가 늘수록 실패를 알아채는 시점이 늦어지고 API 호출 제한에도 가까워진다는 트레이드오프가 있다고 답하면, 값을 그냥 복사한 게 아니라 이해하고 골랐다는 인상을 줍니다.

다음 액션​

재시도와 에러 분기로 노드 하나 단위의 방어는 갖췄습니다. 다음 편은 다른 문제를 다룹니다. 학교 급식 정보를 매일 슬랙으로 보내는 워크플로우인데, 학교코드 하나만 Set 노드에서 바꾸면 다른 학교로도 그대로 재사용되게 설정값을 한곳에 모아 두는 법을 봅니다.