Skip to content

fix: validate storage provider readiness - #1065

Merged
kang-heewon merged 1 commit into
trunkfrom
fix/944-storage-readiness
Jun 22, 2026
Merged

fix: validate storage provider readiness#1065
kang-heewon merged 1 commit into
trunkfrom
fix/944-storage-readiness

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jun 21, 2026

Copy link
Copy Markdown
Member

Fixes #944.

Summary

  • Adds safe diagnostics/readiness providers and stable Croco Problem normalization for Cloudflare Images and Cloudinary storage adapters.
  • Adds shared storage conformance coverage plus env-gated live smoke tests, with Cloudflare metadata limitations documented and tested instead of promoted away.
  • Publishes generated API docs, public API snapshots, Problem registry/cookbook updates, maturity docs, package catalog updates, and patch changesets for both storage providers.

Verification

  • pnpm --filter @croco/storage-cloudflare test
  • pnpm --filter @croco/storage-cloudinary test
  • pnpm --filter @croco/storage-cloudflare typecheck
  • pnpm --filter @croco/storage-cloudinary typecheck
  • pnpm --filter @croco/storage-cloudflare build
  • pnpm --filter @croco/storage-cloudinary build
  • pnpm docs:catalog:check
  • pnpm public-api:check
  • pnpm problem-registry:check
  • pnpm package-manifests:check
  • pnpm changeset-required:check -- --base origin/trunk --head HEAD
  • pnpm exec oxlint packages/storage-cloudflare packages/storage-cloudinary packages/docs/astro.config.mjs packages/docs/tsconfig.typedoc.json
  • git diff --check
  • git diff --name-only --diff-filter=ACM -z | xargs -0 pnpm exec oxfmt --check
  • pre-push pnpm test hook: 223 tasks passed
  • pre-push pnpm typecheck hook: 222 tasks passed

Self-review gates

  • Requirements: storage conformance, metadata semantics, invalid-key/not-found/upstream failure behavior, diagnostics/readiness, opt-in live smoke, and generated API docs are covered.
  • Scope: no list() method was added to StorageProvider; live provider credentials are not required in default CI; Cloudflare remains alpha due documented metadata limits.
  • Failure handling: diagnostics redact sensitive config values and upstream failures normalize into deterministic retryable or terminal provider Problems.

Risk

  • Cloudflare Images still cannot preserve content type or custom metadata through the current provider contract, so it remains alpha.
  • Live smoke tests are intentionally skipped without credentials and were not run against real provider accounts in this branch.

Summary by CodeRabbit

릴리스 노트

  • New Features

    • Cloudflare Images 및 Cloudinary 스토리지 제공자에 진단 기능(헬스 체크, 준비도 확인) 추가
    • 선택적 라이브 스모크 테스트를 통한 실제 연결 점검 지원(환경변수 설정 시)
  • Documentation

    • 진단 제공자, 문제(에러) 코드 체계, 설정/옵션 검증, 관련 복구 가이드 문서 확장
  • Improvements

    • 진단/실패를 표준화한 문제 코드로 일원화하고, 민감 정보는 자동 마스킹하여 반환
  • Tests

    • 진단 및 라이브 스모크 시나리오 검증 테스트 추가/확대

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 22 minutes and 5 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 11bd63ea-2650-4f4c-995e-d82c32394293

📥 Commits

Reviewing files that changed from the base of the PR and between 5892ef3 and db6ef39.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (76)
  • .changeset/storage-provider-readiness.md
  • .github/workflows/ci.yml
  • README.md
  • docs/package-catalog.json
  • docs/package-docs-baseline.json
  • docs/package-docs-report.md
  • docs/problem-code-registry.json
  • packages/create-croco-app/src/tests/PublishedCli.spec.ts
  • packages/docs/astro.config.mjs
  • packages/docs/package.json
  • packages/docs/src/content/docs/api/problems-core/src/classes/Problem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesRetryableUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/createCloudflareImagesResponseProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/normalizeCloudflareImagesError.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/validateCloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImageDetails.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesConfigKey.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesDiagnosticsOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesErrorContext.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesReadinessCheckContext.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesReadinessCheckResult.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareTransformOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareUploadResponse.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/variables/CLOUDFLARE_IMAGES_OPTIONS.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryProvider.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryRetryableUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/getCloudinaryErrorMessage.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/isRetryableCloudinaryStorageError.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/normalizeCloudinaryStorageError.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/validateCloudinaryConfig.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryConfig.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryConfigKey.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryDiagnosticsOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryReadinessCheckContext.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryReadinessCheckResult.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryStorageErrorContext.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryTransformOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryUploadOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/variables/CLOUDINARY_CONFIG.md
  • packages/docs/src/content/docs/api/storage-core/src/classes/BaseStorageProvider.md
  • packages/docs/src/content/docs/en/reference/extension-matrix.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/docs/src/content/docs/en/reference/provider-maturity.md
  • packages/docs/tsconfig.typedoc.json
  • packages/storage-cloudflare/README.md
  • packages/storage-cloudflare/package.json
  • packages/storage-cloudflare/src/index.ts
  • packages/storage-cloudflare/src/libs/CloudflareImagesDiagnosticsProvider.ts
  • packages/storage-cloudflare/src/libs/CloudflareImagesProvider.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesDiagnosticsProvider.spec.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesLiveSmoke.spec.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesProvider.spec.ts
  • packages/storage-cloudflare/tsconfig.json
  • packages/storage-cloudflare/vitest.config.ts
  • packages/storage-cloudinary/README.md
  • packages/storage-cloudinary/package.json
  • packages/storage-cloudinary/src/index.ts
  • packages/storage-cloudinary/src/libs/CloudinaryDiagnosticsProvider.ts
  • packages/storage-cloudinary/src/libs/CloudinaryProvider.ts
  • packages/storage-cloudinary/src/tests/CloudinaryDiagnosticsProvider.spec.ts
  • packages/storage-cloudinary/src/tests/CloudinaryLiveSmoke.spec.ts
  • packages/storage-cloudinary/src/tests/CloudinaryProvider.spec.ts
  • packages/storage-cloudinary/tsconfig.json
  • packages/storage-cloudinary/vitest.config.ts
  • public-api-surface.snapshot.json
  • scripts/package-docs-check.mts
📝 Walkthrough

Walkthrough

@croco/storage-cloudflare@croco/storage-cloudinary 패키지에 DiagnosticsProvider 구현체, 결정적 Problem 서브클래스(missing-config/validation-failed/retryable-upstream/terminal-upstream), 민감값 redaction 로직, 스토리지 컨포먼스·라이브 스모크 테스트를 추가한다. CloudflareImagesProviderCloudinaryProvider의 오류 처리가 새 유틸리티로 이관되며, 두 패키지의 생성 API 문서가 추가되고 storage-cloudinary가 beta로 승격된다.

Changes

스토리지 공급자 준비도 강화

Layer / File(s) Summary
Cloudflare Images 진단 타입 및 Problem 클래스 정의
packages/storage-cloudflare/src/libs/CloudflareImagesDiagnosticsProvider.ts
에러 컨텍스트 타입 4종(ErrorContext, ReadinessCheckContext/Result, DiagnosticsOptions), Problem 서브클래스 4종, validateCloudflareImagesOptions, normalizeCloudflareImagesError, createCloudflareImagesResponseProblem, sanitizeDiagnosticValue 등 분류·검증·마스킹 유틸리티를 정의한다.
CloudflareImagesDiagnosticsProvider getHealth 구현 및 공개 API 노출
packages/storage-cloudflare/src/libs/CloudflareImagesDiagnosticsProvider.ts, packages/storage-cloudflare/src/index.ts, packages/storage-cloudflare/package.json, packages/storage-cloudflare/tsconfig.json, packages/storage-cloudflare/vitest.config.ts
getHealth의 unhealthy/healthy/degraded 분기를 구현하고, 진단 클래스·Problem·타입을 index.ts에서 re-export한다. @croco/diagnostics-core 의존성 추가 및 Vitest alias 설정도 포함된다.
CloudflareImagesProvider 오류 처리 fetchCloudflare로 이관
packages/storage-cloudflare/src/libs/CloudflareImagesProvider.ts
put/delete/getMetadata/getUploadIntent/getSigningKey에서 직접 fetch를 fetchCloudflare 래퍼로 교체하고 createCloudflareImagesResponseProblem으로 예외를 표준화한다.
Cloudflare 진단·라이브 스모크·Provider 테스트 갱신
packages/storage-cloudflare/src/tests/*
DiagnosticsProvider 단위 테스트 4종, env-gated 라이브 스모크 테스트를 추가한다. 기존 Provider 테스트의 예외 단언을 Problem code 기반으로 갱신한다.
Cloudinary 진단 타입 및 Problem 클래스 정의
packages/storage-cloudinary/src/libs/CloudinaryDiagnosticsProvider.ts
transient 코드 상수, 에러 컨텍스트 타입, Problem 서브클래스 4종, normalizeCloudinaryStorageError, isRetryableCloudinaryStorageError, sanitizeDiagnosticValue 등을 정의한다.
CloudinaryDiagnosticsProvider getHealth 구현 및 공개 API 노출
packages/storage-cloudinary/src/libs/CloudinaryDiagnosticsProvider.ts, packages/storage-cloudinary/src/index.ts, packages/storage-cloudinary/package.json, packages/storage-cloudinary/tsconfig.json, packages/storage-cloudinary/vitest.config.ts
getHealth의 4가지 분기를 구현하고 진단 클래스·타입을 index.ts에서 re-export한다. @croco/diagnostics-core·@croco/testing 의존성 추가 및 Vitest alias 설정도 포함된다.
CloudinaryProvider 오류 처리 통합
packages/storage-cloudinary/src/libs/CloudinaryProvider.ts
로컬 에러 유틸을 제거하고 CloudinaryDiagnosticsProvider 헬퍼로 대체한다. toCloudinarySdkError 추가, 재시도 정책이 isRetryableCloudinaryStorageError를 사용하도록 변경된다.
Cloudinary 진단·라이브 스모크·컨포먼스·Provider 테스트
packages/storage-cloudinary/src/tests/*
DiagnosticsProvider 단위 테스트 4종, opt-in 라이브 스모크, createStorageProviderConformanceSuite 기반 컨포먼스 스위트와 인메모리 백엔드 헬퍼를 추가한다. 기존 Provider 테스트 단언도 code 기반으로 갱신된다.
storage-cloudflare 생성 API 문서
packages/docs/src/content/docs/api/storage-cloudflare/...
DiagnosticsProvider, Problem 클래스, CloudflareImagesProvider, 함수·타입 별칭·변수에 대한 API 문서 페이지를 신규 추가한다. BaseStorageProvider·Problem.md도 갱신된다.
storage-cloudinary 생성 API 문서
packages/docs/src/content/docs/api/storage-cloudinary/...
DiagnosticsProvider, Problem 클래스, CloudinaryProvider, 함수·타입 별칭·변수에 대한 API 문서 페이지를 신규 추가한다.
문서 빌드 설정, 카탈로그 메타데이터, 성숙도 지표 갱신
packages/docs/astro.config.mjs, docs/package-catalog.json, docs/problem-code-registry.json, README.md, public-api-surface.snapshot.json, .github/workflows/ci.yml
두 패키지를 TypeDoc entryPoint에 추가하고, storage-cloudinary를 beta로 승격한다. 8개 신규 Problem 코드 등록, API 문서 drift 검사·CI 경로 필터 확장도 포함된다.

Sequence Diagram(s)

sequenceDiagram
  participant Consumer
  participant DiagnosticsProvider as CloudflareImages/Cloudinary<br/>DiagnosticsProvider
  participant validateConfig as validateConfig()
  participant readinessCheck as readinessCheck()
  participant normalizeError as normalizeError()

  Consumer->>DiagnosticsProvider: getHealth(signal?)
  DiagnosticsProvider->>validateConfig: Partial<Config> 검증
  alt 검증 실패 (missing-config / validation-failed)
    validateConfig-->>DiagnosticsProvider: throw Problem
    DiagnosticsProvider-->>Consumer: HealthStatus { status: "unhealthy", problem }
  else readinessCheck 미설정
    DiagnosticsProvider-->>Consumer: HealthStatus { status: "healthy", liveCheck: "not_configured" }
  else readinessCheck 성공
    DiagnosticsProvider->>readinessCheck: { config, signal } 전달
    readinessCheck-->>DiagnosticsProvider: ReadinessCheckResult (sanitize 후 반영)
    DiagnosticsProvider-->>Consumer: HealthStatus { status: "healthy", liveCheck: "passed", details }
  else readinessCheck 실패/예외
    readinessCheck-->>DiagnosticsProvider: throw error
    DiagnosticsProvider->>normalizeError: error → Problem 변환
    normalizeError-->>DiagnosticsProvider: retryable-upstream / terminal-upstream / validation-failed
    DiagnosticsProvider-->>Consumer: HealthStatus { status: "degraded", problem, details }
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • croco-dev/framework#760: docs/package-catalog.jsonextensionMatrix 메타데이터 생성 흐름을 도입하며, 이번 PR이 storage-cloudflare/storage-cloudinary 행의 features를 갱신하는 것과 직접 연관된다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 PR의 주요 변화인 스토리지 공급자 준비도 검증 추가를 명확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed PR의 모든 변경사항이 #944의 요구사항(진단, 준비도 검증, 문제 정규화, API 문서, 라이브 스모크 테스트)을 충족합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 스토리지 공급자 준비도 구현과 직접 관련되며, 범위 경계(list() 메서드 추가, 필수 자격증명) 내에 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/944-storage-readiness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown

📊 Benchmark Results

❌ Some benchmarks failed

Gate failures

  • CrocoApp constructor: p75 8.5μs exceeds baseline 3.4μs by more than 20%
  • CrocoApp lambdaHandler (10 controllers): p75 219.6μs exceeds baseline 33.3μs by more than 20%
  • Lambda cold-start simulation: p75 401.4μs exceeds baseline 70.2μs by more than 20%
  • Lambda cold-start with headers: p75 357.1μs exceeds baseline 66.7μs by more than 20%
  • Lambda cold-start with binary body: p75 319.8μs exceeds baseline 63.2μs by more than 20%
  • Lambda cold-start with query params: p75 278.1μs exceeds baseline 63.9μs by more than 20%
  • Lambda cold-start with authorizer context: p75 278.7μs exceeds baseline 59.8μs by more than 20%
  • Lambda cold-start realistic scenario: p75 278.0μs exceeds baseline 60.2μs by more than 20%
  • EventBusConfig.start (10 handlers): p75 1.7μs exceeds baseline 0.9μs by more than 20%
  • EventPublisher.publishNow single event: p75 1.9μs exceeds baseline 1.1μs by more than 20%
  • DefaultHandlerResolver.resolve × 10: p75 0.1μs exceeds baseline 0.0μs by more than 20%
  • Container.get singleton (cold): p75 58.1μs exceeds baseline 0.6μs by more than 20%
  • Container.register × 50 components: p75 2.8ms exceeds baseline 12.1μs by more than 20%
  • Container.validate (50 components): p75 3.0ms exceeds baseline 29.7μs by more than 20%
  • Container.get singleton (warm): p75 1.6μs exceeds baseline 0.3μs by more than 20%
  • lambdaPreset config creation: p75 1.4μs exceeds baseline 1.0μs by more than 20%
Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 8.5μs 30.0ms 3.4μs +152.8% -
CrocoApp lambdaHandler (10 controllers) 219.6μs 50.0ms 33.3μs +559.5% -
Lambda cold-start simulation 401.4μs 80.0ms 70.2μs +472.1% -
Lambda cold-start with headers 357.1μs 80.0ms 66.7μs +435.0% -
Lambda cold-start with binary body 319.8μs 80.0ms 63.2μs +406.3% -
Lambda cold-start with query params 278.1μs 80.0ms 63.9μs +335.4% -
Lambda cold-start with authorizer context 278.7μs 80.0ms 59.8μs +366.1% -
Lambda cold-start realistic scenario 278.0μs 80.0ms 60.2μs +362.1% -
EventBusConfig.start (10 handlers) 1.7μs 10.0ms 0.9μs +90.1% -
EventPublisher.publishNow single event 1.9μs 2.0ms 1.1μs +73.9% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.0μs +90.5% -
Container.get singleton (cold) 58.1μs 5.0ms 0.6μs +9203.4% -
Container.register × 50 components 2.8ms 10.0ms 12.1μs +22927.4% -
Container.validate (50 components) 3.0ms 20.0ms 29.7μs +9970.8% -
Container.get singleton (warm) 1.6μs 500.0μs 0.3μs +449.0% -
TelemetryRuntime.init (lambda preset) 1.1ms 200.0ms 69.3ms -98.4% -
lambdaPreset config creation 1.4μs 2.0ms 1.0μs +38.2% -

Updated: 2026-06-22T09:18:52.988Z · Commit: ae8bee3

@kang-heewon
kang-heewon force-pushed the fix/944-storage-readiness branch 4 times, most recently from 3c7d335 to 0fb7711 Compare June 21, 2026 16:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesMissingConfigProblem.md`:
- Line 8: The class description for CloudflareImagesMissingConfigProblem is
incorrectly generic and describes a base Problem class instead of the specific
purpose of this class. Update the class description on line 8 to accurately
reflect that CloudflareImagesMissingConfigProblem is a specialized Problem type
that represents the scenario when Cloudflare Images configuration is missing or
not properly configured, rather than describing it as a generic RFC 7807 Problem
Details base class.

In `@packages/storage-cloudflare/src/tests/CloudflareImagesLiveSmoke.spec.ts`:
- Around line 41-56: The error throwing pattern is inconsistent in the readiness
check logic. The first error throw (when response.ok is false) creates an Error
instance with Object.assign to add properties, but the second error throw (when
payload.success is false) throws a plain object instead of an Error instance.
Make both error throws consistent by changing the second throw statement to use
Object.assign with a new Error instance, similar to how the first error is
constructed, ensuring both paths throw proper Error instances with their
respective properties (code and message) attached.

In `@packages/storage-cloudinary/src/libs/CloudinaryDiagnosticsProvider.ts`:
- Around line 297-310: The getCloudinaryErrorMessage() function only extracts
the top-level message property but Cloudinary SDK returns errors in a nested
structure like { error: { message } }. Add an additional check in
getCloudinaryErrorMessage() to also look for the message property within the
nested error.error structure before returning the fallback. Similarly, update
the createCloudinaryStorageErrorContext() function to parse nested error
properties by checking record?.error for additional fields like status,
http_code, and statusCode that may be nested within the error object, ensuring
these properties are extracted and included in the error context returned by the
function.

In `@packages/storage-cloudinary/src/libs/CloudinaryProvider.ts`:
- Around line 192-195: In the HTTP fetch failure handling block where
createHttpError is being called with fetchedResponse.status, replace this
generic Error creation with a Problem-based exception by calling
normalizeCloudinaryStorageError instead. Pass the appropriate error context and
the status code to normalizeCloudinaryStorageError, then throw the result
directly. This ensures consistency with the file's exception contract of
throwing only Problem subclasses rather than generic Error instances.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 702e2939-7c5e-4a13-a5ac-0997861f78a5

📥 Commits

Reviewing files that changed from the base of the PR and between 355fe56 and 0fb7711.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (74)
  • .changeset/storage-provider-readiness.md
  • .github/workflows/ci.yml
  • README.md
  • docs/package-catalog.json
  • docs/package-docs-baseline.json
  • docs/package-docs-report.md
  • docs/problem-code-registry.json
  • packages/docs/astro.config.mjs
  • packages/docs/package.json
  • packages/docs/src/content/docs/api/problems-core/src/classes/Problem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesRetryableUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/createCloudflareImagesResponseProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/normalizeCloudflareImagesError.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/validateCloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImageDetails.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesConfigKey.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesDiagnosticsOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesErrorContext.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesReadinessCheckContext.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesReadinessCheckResult.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareTransformOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareUploadResponse.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/variables/CLOUDFLARE_IMAGES_OPTIONS.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryProvider.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryRetryableUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/classes/CloudinaryValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/getCloudinaryErrorMessage.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/isRetryableCloudinaryStorageError.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/normalizeCloudinaryStorageError.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/functions/validateCloudinaryConfig.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryConfig.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryConfigKey.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryDiagnosticsOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryReadinessCheckContext.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryReadinessCheckResult.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryStorageErrorContext.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryTransformOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/type-aliases/CloudinaryUploadOptions.md
  • packages/docs/src/content/docs/api/storage-cloudinary/src/variables/CLOUDINARY_CONFIG.md
  • packages/docs/src/content/docs/api/storage-core/src/classes/BaseStorageProvider.md
  • packages/docs/src/content/docs/en/reference/extension-matrix.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/docs/src/content/docs/en/reference/provider-maturity.md
  • packages/docs/tsconfig.typedoc.json
  • packages/storage-cloudflare/README.md
  • packages/storage-cloudflare/package.json
  • packages/storage-cloudflare/src/index.ts
  • packages/storage-cloudflare/src/libs/CloudflareImagesDiagnosticsProvider.ts
  • packages/storage-cloudflare/src/libs/CloudflareImagesProvider.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesDiagnosticsProvider.spec.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesLiveSmoke.spec.ts
  • packages/storage-cloudflare/src/tests/CloudflareImagesProvider.spec.ts
  • packages/storage-cloudflare/tsconfig.json
  • packages/storage-cloudflare/vitest.config.ts
  • packages/storage-cloudinary/README.md
  • packages/storage-cloudinary/package.json
  • packages/storage-cloudinary/src/index.ts
  • packages/storage-cloudinary/src/libs/CloudinaryDiagnosticsProvider.ts
  • packages/storage-cloudinary/src/libs/CloudinaryProvider.ts
  • packages/storage-cloudinary/src/tests/CloudinaryDiagnosticsProvider.spec.ts
  • packages/storage-cloudinary/src/tests/CloudinaryLiveSmoke.spec.ts
  • packages/storage-cloudinary/src/tests/CloudinaryProvider.spec.ts
  • packages/storage-cloudinary/tsconfig.json
  • packages/storage-cloudinary/vitest.config.ts
  • public-api-surface.snapshot.json
💤 Files with no reviewable changes (1)
  • docs/package-docs-baseline.json

Comment thread packages/storage-cloudinary/src/libs/CloudinaryProvider.ts Outdated
@kang-heewon
kang-heewon force-pushed the fix/944-storage-readiness branch from 0fb7711 to 228b3a2 Compare June 21, 2026 16:44
@kang-heewon
kang-heewon force-pushed the fix/944-storage-readiness branch 5 times, most recently from 800dc61 to 5892ef3 Compare June 22, 2026 08:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/create-croco-app/src/tests/PublishedCli.spec.ts`:
- Around line 13-19: There is an inconsistency between the test validation and
package dependencies. The requiredPackageArtifacts array in PublishedCli.spec.ts
includes a check for diagnostics-core artifacts via
requiredLibraryArtifacts("diagnostics-core"), but `@croco/diagnostics-core` is not
listed as a dependency in the package.json. Since the generated templates
(saasDemo.ts and package.json.hbs) actually import DiagnosticsCollector from
`@croco/diagnostics-core`, you need to resolve this mismatch by either: (1)
removing the requiredLibraryArtifacts("diagnostics-core") line from the
requiredPackageArtifacts array in PublishedCli.spec.ts if it's not actually
needed, or (2) adding `@croco/diagnostics-core` as a dependency to package.json to
match what the templates require. Verify which approach is correct by checking
if the generated templates actually need the diagnostics-core package.

In `@README.md`:
- Around line 394-395: The package count numbers on lines 394-395 in the
README.md table for the beta and alpha/WIP status rows are incorrect and need to
be updated to match the actual number of packages in the matrix. Change the 57
to 13 for the 🟡 beta status row and change the 28 to 25 for the 🔴 alpha/WIP
status row to accurately reflect the actual package counts in the table.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dca0feab-1e7e-480b-8701-3d5cbad2e446

📥 Commits

Reviewing files that changed from the base of the PR and between 0fb7711 and 5892ef3.

📒 Files selected for processing (23)
  • .changeset/storage-provider-readiness.md
  • .github/workflows/ci.yml
  • README.md
  • docs/package-catalog.json
  • docs/package-docs-baseline.json
  • docs/package-docs-report.md
  • docs/problem-code-registry.json
  • packages/create-croco-app/src/tests/PublishedCli.spec.ts
  • packages/docs/astro.config.mjs
  • packages/docs/package.json
  • packages/docs/src/content/docs/api/problems-core/src/classes/Problem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesRetryableUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/createCloudflareImagesResponseProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/normalizeCloudflareImagesError.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/validateCloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImageDetails.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesConfigKey.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesDiagnosticsOptions.md
💤 Files with no reviewable changes (13)
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/normalizeCloudflareImagesError.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/createCloudflareImagesResponseProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesDiagnosticsOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/functions/validateCloudflareImagesOptions.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesMissingConfigProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesDiagnosticsProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesProvider.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImageDetails.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesValidationProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesTerminalUpstreamProblem.md
  • packages/docs/src/content/docs/api/storage-cloudflare/src/classes/CloudflareImagesRetryableUpstreamProblem.md
  • docs/package-docs-baseline.json
  • packages/docs/src/content/docs/api/storage-cloudflare/src/type-aliases/CloudflareImagesConfigKey.md

Comment thread packages/create-croco-app/src/tests/PublishedCli.spec.ts
Comment thread README.md Outdated
@kang-heewon
kang-heewon force-pushed the fix/944-storage-readiness branch from 5892ef3 to db6ef39 Compare June 22, 2026 09:12
@kang-heewon
kang-heewon merged commit db90918 into trunk Jun 22, 2026
7 checks passed
@kang-heewon
kang-heewon deleted the fix/944-storage-readiness branch June 22, 2026 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[storage] Promote Cloudflare Images and Cloudinary providers with full storage readiness

1 participant