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

Jin's Lab

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

api-automation

Blogger 라벨 길이 제한 400 에러와 큐 정체 해결한 삽질기

J.Lab ·
목차

    최근 개인 프로젝트로 진행 중인 Blogger 자동 포스팅 도구에서 원인 모를 에러가 발생했다. API 요청 시 계속해서 400 에러가 반환되며 포스팅 발행이 멈추는 현상이었다. 처음에는 API 문서만 보고 단순한 일시적 오류이거나 필수 파라미터가 누락된 줄로만 알았다.

    하지만 에러가 발생한 글 하나 때문에 뒤이어 대기 중이던 수많은 포스팅 큐가 통째로 정체되는 치명적인 상황이 벌어졌다. 이 문제를 해결하기 위해 최근 며칠간 밤을 새우며 겪은 눈물겨운 삽질과 마침내 찾아낸 해결책을 공유하고자 한다.

    대기 큐가 99퍼센트에서 멈춰 정체된 현상을 나타내는 네이비와 실버 톤의 아이소메트릭 일러스트

    엉뚱한 곳에서 헤맸던 날짜 포맷의 늪

    가장 처음 의심했던 용의자는 등록일(published) 날짜 포맷이었다. 로그를 확인했을 때 밀리초 단위가 누락되어 발생하는 오류인 줄 알고 날짜 변환 함수인 toBloggerRfc3339를 도입하고 실패 시 예외 처리를 하는 폴백(Fallback) 로직을 추가했다.

    하지만 날짜 포맷을 정교하게 다듬고 예외 처리를 꼼꼼하게 넣었음에도 불구하고 400 에러는 여전히 발생했다. 큐가 여전히 꽉 막혀 꼼짝도 하지 않는 모습을 보며 뒤통수가 얼얼해지는 느낌을 받았다.

    결정적인 단서는 예외 처리 폴백 로직이 제대로 작동하면서 포착되었다. 폴백 로직이 아예 published 필드를 완전히 제거하고 재시도하도록 설계했음에도 불구하고 동일하게 INVALID_ARGUMENT와 함께 400 에러가 떨어졌기 때문이다. 이는 날짜 포맷이 원인이 아니라, 두 요청에 공통으로 들어가는 다른 필드에 진짜 범인이 숨어있음을 의미했다.

    데이터베이스 테이블 위의 코드 블록을 돋보기로 검사하며 원인을 찾는 모습을 묘사한 네이비 및 실버 톤의 일러스트

    범인은 날짜가 아니라 200자 제한의 라벨이었다

    모든 공통 필드를 꼼꼼히 뜯어보던 중 Blogger 라벨에 눈길이 갔다. 검색을 거듭한 끝에 아주 놀라운 사실을 발견했다. Blogger는 개별 포스트에 달 수 있는 라벨 개수 제한인 20개보다, 모든 라벨의 합계 길이 제한인 200자 제한이 먼저 작동한다는 사실이었다.

    이 200자 제한에는 콤마와 공백까지 모두 포함된다. 나는 콘텐츠 분류를 세분화하기 위해 띄어쓰기가 포함된 긴 멀티워드 라벨을 아낌없이 집어넣고 있었다. 여러 개의 긴 라벨이 콤마로 연결되다 보니 합계 길이가 손쉽게 200자를 초과해 버렸던 것이다.

    그 결과 Blogger API 측에서는 이를 잘못된 인자(INVALID_ARGUMENT)로 판단하고 400 에러를 뱉어낸 것이었다. 원인을 알고 나니 허탈하면서도 문제를 해결할 수 있다는 실마리를 얻어 무척 기뻤다.

    데이터 스트림이 안전선에 맞춰 깔끔하게 잘려나가는 모습을 나타내는 네이비와 실버 색상의 입체 일러스트

    안전하게 컷오프하는 해결책과 동반 발견한 버그

    해결을 위해 라벨의 총길이를 안전하게 가공해 주는 capBloggerLabels()라는 헬퍼 함수를 구현했다. 이 함수는 단순한 개수 제한뿐만 아니라, 콤마 구분자를 포함한 누적 문자열 길이가 190자를 넘지 않도록 안전선을 확실히 그어주도록 설계했다.

    • 라벨을 순회하며 구분자를 포함한 총 문자열 길이를 실시간 계산
    • 안전 마진을 두어 누적 190자까지만 라벨을 수용하고 이후는 과감히 컷
    • 최종 라벨 개수도 최대 20개 상한선을 넘지 않도록 이중 안전장치 마련

    이 작업을 진행하면서 또 다른 심각한 설계 결함도 발견했다. 작성해 둔 스크립트가 대기 상태인 행 중에서 항상 첫 번째 행만 가져와서 처리하도록 고정되어 있었던 것이다. 이 때문에 라벨 길이 초과로 에러가 난 특정 포스트 한 건이 큐의 맨 앞에서 버티고 서 있으니, 뒤에 있는 모든 정상 포스트들까지 전부 실행되지 못하고 큐 정체 현상이 발생했던 것이었다.

    라벨 길이를 안전하게 잘라주는 보정 함수를 적용하고 나니 막혀있던 대기 행들이 거짓말처럼 한 번에 쭉 빠져나갔다. API 통신 시에는 사소한 문자열 제한조건 하나가 전체 시스템을 마비시킬 수 있음을 뼈저리게 배운 유익한 경험이었다.

    api-automation blogger-api blogger-error-400 invalid-argument label-length-limit queue-stuck
    ← 이전 글
    최근 게시물
    다음 글 →
    이전 게시물
    ≡ 글 목록으로
    소개
    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