path
Jin's Lab
코드로 실험하고 기록하는 개발 일지 · J.Lab

Jin's Lab

코드로 실험하고 기록하는 개발 일지. 커리어와 삶의 방향을 탐색하며 기록하는 공간입니다

APIIntegration

GAS 오류 처리: 분명 실패했는데 성공으로 뜨는 버그 해결기

J.Lab ·
목차

    최근 구글 앱스 스크립트(Google Apps Script, 이하 GAS)를 활용해 블로그 포스팅 과정을 자동화하는 작업을 신나게 진행하고 있었다. 인공지능 API와 구글 시트, 그리고 Blogger API까지 연동하여 버튼 하나만 누르면 글이 올라가는 멋진 시스템을 구축하는 중이었다. 그런데 이상하게도 분명 API 요청 중에 심각한 문제가 생겼음에도 불구하고, 구글 콘솔의 GAS 실행 로그에는 상태가 항상 정상적인 '완료됨'으로 표시되는 기이한 현상이 일어났다.

    포스팅은 실제로 블로그에 업로드되지 않았는데 로그만 계속해서 성공으로 찍히니 도무지 원인을 찾을 수가 없었다. 에러가 나면 당연히 빨간색 경고등이 켜지며 실행 실패가 떠야 정상인데, 시스템은 아무 일 없었다는 듯 평온했다. 이 답답한 현상을 해결하기 위해 며칠간 코드 속을 파헤치며 치열하게 추적해 들어갔다.

    실패가 성공으로 둔갑하는 GAS 실행 로그의 비밀

    가장 먼저 작성해 두었던 자동화 스크립트의 에러 제어 코드를 찬찬히 뜯어보기로 했다. 그리고 얼마 지나지 않아 허무할 정도로 결정적인 원인을 발견했다. 문제는 내가 작성한 외부 try catch 블록의 허술한 예외 처리 구조에 있었다.

    성공 메시지 이면에 오류 경고가 감추어진 모습을 표현한 깔끔한 아이소메트릭 대시보드 일러스트

    일반적으로 API 호출이나 데이터 처리를 하다가 예외가 발생하면 catch 블록으로 제어권이 넘어간다. 나는 외부 catch 블록 안에서 단순히 오류 메시지를 로깅하는 함수만 실행하도록 코드를 작성해 두었다. 하지만 이렇게 에러를 캐치한 뒤 외부로 다시 던져주지 않으면, GAS 시스템은 이 스크립트가 아무 문제 없이 예외 처리를 끝내고 정상 종료된 것으로 판단한다.

    이것이 바로 개발자가 가장 두려워해야 할 오류 은폐 현상이었다. 로깅 시스템만 믿고 있다가 실제로는 심각한 API 전송 실패가 일어났는데도 '작업 완료'라는 거짓 메시지에 속아 넘어가고 있었던 것이다. 디버깅을 어렵게 만드는 가장 전형적인 실수였다.

    원인은 non-ASCII 라벨과 조용한 오류 은폐

    그렇다면 왜 자꾸 Blogger API 호출에서 오류가 났던 것일까? 그 근본적인 에러 원인은 인공지능 Gemini가 생성해 준 게시물의 태그(라벨)에 있었다. 최근 도입한 기능 중 하나가 본문을 분석해 자동으로 라벨을 생성해 주는 필터였는데, 여기서 문제가 발생했다.

    비아스키 문자 라벨 데이터 패킷이 서버 장벽에서 차단당하는 오류 상황을 그린 아이소메트릭 일러스트

    Gemini가 가끔 한글이나 특수문자가 섞인 non-ASCII 문자를 라벨로 추천하는 경우가 있었다. 불행히도 Blogger API는 이러한 non-ASCII 라벨이 데이터에 포함되어 전송되면 곧바로 400 Bad Request 에러를 뿜어내며 요청을 거부하는 스펙을 가지고 있었다.

    만약 제대로 된 예외 처리가 작동했다면 즉시 실행 실패 로그가 남고 나는 곧바로 문제를 인지했을 것이다. 하지만 외부 catch 블록에서 예외를 먹어버린 채 로그만 살짝 남겨두다 보니, 실제로 글이 누락되어도 시스템 레벨에서는 오류가 전혀 보이지 않는 조용한 실패 상태가 지속되었다.

    해결책: throw e 추가와 라벨 필터링

    문제를 정확히 파악했으니 이제 코드를 전면적으로 수정할 차례였다. 가장 먼저 해결한 것은 예외 처리의 핵심 원칙을 다시 바로잡는 일이었다. catch 블록 마지막 줄에 주저 없이 throw e 코드를 추가해 주었다.

    코딩 화면에서 예외를 던지는 throw 구문이 강조되어 디버깅되는 모습을 묘사한 아이소메트릭 일러스트

    이렇게 throw e를 추가하자마자, 마침내 API 호출 실패 시 GAS 실행 로그에 선명한 빨간색 오류 표시가 뜨기 시작했다. 에러가 발생하면 전체 프로세스가 정상적으로 멈추고 어디가 고장 났는지 대시보드에서 즉시 시각적으로 파악할 수 있게 되었다.

    여기에 더해, 근본적으로 Blogger API 400 오류를 방지하기 위해 Gemini가 생성한 라벨 문자열에 정규 표현식 필터링을 더했다. non-ASCII 문자를 완벽하게 무시하거나 제거해 주는 정규식 처리를 적용함으로써, 오직 영문과 호환되는 안전한 라벨만 API 요청에 담겨 전송되도록 시스템 안정성을 끌어올렸다.

    이번 삽질을 겪으며 예외 처리 시 에러를 잡아서 그냥 뭉개지 않고 다시 던져주는 습관이 얼마나 중요한지 절실히 깨달았다. 에러를 제대로 마주해야 버그를 빠르게 잡을 수 있다는 기본 중의 기본을 다시금 되새긴 값진 경험이었다. 혹시 비슷한 문제로 머리를 싸매고 있다면 당장 자신의 try catch 블록 끝에 throw e가 누락되지 않았는지 점검해 보길 바란다.

    APIIntegration BloggerAPI Debugging ErrorHandling GoogleAppsScript JavaScript
    ← 이전 글
    최근 게시물
    다음 글 →
    이전 게시물
    ≡ 글 목록으로
    소개
    path
    J.Lab

    커리어와 삶의 방향을 탐색하며
    기록하는 공간입니다

    카테고리
    403 Forbidden Error 1 AdSense 1 AdSense Bot Detection 1 AI Automation 1 AI Image Generation 1 ai-automation 2 AI-Prompting 1 AIBlogAutomation 1 AICodeLog 1 AIContentGeneration 1 AIImageGeneration 1 AIWritingErrors 1 API Automation 2 API Retry Design 1 api-automation 1 API-Deprecation 1 api-error 1 api-fallback 1 api-retry-strategy 1 api-troubleshooting 1 APIDebugging 1 APIError 1 APIErrorHandling 1 APIIntegration 1 APITokenRenewal 1 AppsScript 1 appsScriptAutomation 1 AutomatedBlogging 1 automation 1 Automation 2 AutomationTroubleshooting 1 Backoff Algorithm 1 Base64Encoding 1 BatchProcessing 1 blog-automation 1 blog-customization 1 blog-migration 3 Blog-Sorting 1 blog-strategy 1 blog-theme-customization 1 blog-workflow 1 blogautomation 1 BlogAutomation 2 Blogger 4 Blogger API 2 Blogger Automation 1 Blogger SEO 1 blogger-api 3 blogger-automation 1 blogger-error-400 1 blogger-labels 1 blogger-seo 1 blogger-tips 1 Blogger-Tips 1 BloggerAPI 3 BloggerBypath 1 BloggerCustomization 2 BloggerFavicon 1 BloggerTemplate 1 BloggerTemplateEditing 1 BloggerTheme 1 BloggerThemeCustomization 1 BloggerXMLStructure 1 Blogging-Automation 1 BloggingTools 1 BlogQuality 1 BlogSpot 1 BWidgetBIncludable 1 CardClickHandler 1 CDATA 1 clamping-text 1 Code Integration 1 codelog 1 CodeLog 1 codeRefactoring 1 contentsequencing 1 cost-reduction 1 CSSOverlay 1 data-parsing 1 DatabaseDesign 1 DataRecovery 1 DateInjection 1 Debugging 2 dev-journey 1 DeveloperJourney 2 DevJourney 1 display-none-seo 1 dom-manipulation 1 dynamic-menu 1 Error-Handling 1 ErrorHandling 1 Execution Timeout 1 ExecutionLimit 1 exponential-backoff 1 FactChecking 1 FaviconEmbedding 1 Feed-API 1 filesystem 1 Flat Illustration 1 FluxModel 1 FreeAIImage 1 FrontEndDev 1 FrontendTips 1 GAS Blogger API 1 gas-automation 1 gas-optimization 1 gas-trigger 1 GASTimeout 1 gasTriggerManagement 1 GCP Project Linkage 1 Gemini 1 Gemini API 1 gemini-api 1 GeminiAPI 1 GeminiPrompt 1 GeminiPromptEngineering 1 GmailRestrictions 1 Google Apps Script 7 Google Discover 1 google-apps-script 3 Google-Apps-Script 1 google-blogger 1 googleAppsScript 1 GoogleAppsScript 6 googlesapps-script 1 hero-image 1 HTMLWidgetBlogger 1 http-429 1 HuggingFace 1 HuggingFaceAPI 1 ico-generator 1 Image Optimization 1 image-automation 1 image-optimization 1 In-App Browser 1 invalid-argument 1 javascript 3 JavaScript 2 javascript-automation 1 javascript-toc 1 jlab-codelog 1 JLabDevLog 1 json-schema 1 label-length-limit 1 linux 1 meta-description 1 Negative Prompt 1 notion-api 1 notion-database 1 notion-gas-integration 1 NotionAPI 1 NotionAutomation 1 notionintegration 1 NotionIntegration 1 OAuth Scope 1 pagination 1 payload-validation 1 permalink-management 1 PersonaDesign 1 pil-image-processing 1 Pinterest 1 Pollinations 1 Pollinations Flux 1 pollinations-api 1 PollinationsAI 1 PositionAbsolute 1 Prompt Design 1 Prompt Engineering 1 prompt-engineering 1 Prompt-Engineering 1 PromptEngineering 1 publishorder 1 python-favicon 1 queue-stuck 1 RandomDelay 1 rate-limiting 1 Refactoring 1 rfc3339 2 Robots Meta Tag 1 RSS Feed 1 scriptNotFound 1 Search Engine Optimization 2 Search-Engine-Optimization 1 SEO Tips 1 seo-optimization 4 SEO-Optimization 1 seriesmanagement 1 SidebarLinks 1 SNSMarketing 1 SVGIcon 1 table-of-contents 1 TechJournal 1 Template 1 ThreadsAPI 1 tistory-migration 1 transparent-favicon 1 triggerCleanup 1 Troubleshooting 1 unzip 1 URL Slug 1 vanilla-js 1 Web Development 1 Web Publishing 2 Web Security 1 web-development 1 Web-Development 1 web-development-tips 1 web-performance 1 web-scraping 1 WebAccessibility 1 WebDevelopment 3 WebDevelopmentTips 1 WebDevJourney 1 windows 1 WorkflowAutomation 1 XMLParser 1 XMLSpecialCharacters 1 XMLTheme 1 zip 1
    인기 글
    GAS에서 Blogger API 403 오류 완전 정복 — appsscript.json 스코프와 GCP 프로젝트 연결
    GAS에서 Blogger API 403 오류 완전 정복 — appsscript.json 스코프와 GCP 프로젝트 연결
    Google Apps Script 실행 시간 6분 제한 — Gmail 계정 함정과 랜덤 딜레이 설계
    Google Apps Script 실행 시간 6분 제한 — Gmail 계정 함정과 랜덤 딜레이 설계
    Blogger 테마 XML 직접 뜯어봤더니 알게 된 것들
    Blogger 테마 XML 직접 뜯어봤더니 알게 된 것들
    다른 블로그
    IssueLog
    IssueLog
    issuelog.jinbytes.com
    KidStory
    KidStory
    kidstory.jinbytes.com
    IT Story
    IT Story
    jinbytes.com
    © Jin's Lab · J.Lab · All Rights Reserved
    jinbytes.com · Powered by Blogger