Repository navigation
Conversation
…oyed yet Editing a banner with a newly uploaded image made the whole CMS preview fail with a gateway timeout: the image is not on the deployed images manifest yet, so `useSSRPicture` could not resolve its size and `getPicture` threw "`aspectRatio` must be provided for remote images" in the middle of the SSR stream, hanging the response until the Cloud Run request timeout. When the image size is unknown, `useSSRPicture` now renders the original file (plain `<img src>`, no optimized sources) and logs a warning instead of throwing. Images with known size keep the same optimized output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vitorrgg
left a comment
There was a problem hiding this comment.
Revisão
A correção está certa e resolve o que se propõe: nada bloqueante. Dois ajustes pequenos (itens 1 e 2) entram em um commit a seguir nesta mesma branch; os itens 3 e 4 ficam como registro.
O que foi conferido
- Premissa da PR: sem
aspectRatioogetPicturesempre lançava erro. Confere: tantogetBuiltPicture(runtime) quanto o getter doPicture.astropassam porcreatePictureGetter, que lança antes de qualquer outra coisa. Então o caminho com tamanho conhecido não muda. - Testes:
vitest runpassa 8/8. Com ouse-ssr-picture.tsdamain, o primeiro caso falha com`aspectRatio` must be provided for remote images, o mesmo erro do log de produção. - Lint: ESLint com a config do storefront sem avisos nos dois arquivos.
- Não conferido: ponta a ponta numa loja com o pacote alterado (igual ao que a PR já declara).
Achados
1. Picture.astro monta uma URL inválida no novo fallback (baixo)
src/lib/components/Picture.astro:86 faz imgAttrs.src += versionSuffix, e o sufixo é &V=<rand>. Isso pressupõe um src que já tem query string (/_image?href=...). Com o fallback, o src passa a ser o caminho original, e o resultado é /img/uploads/banner.jpg&V=123.
Só afeta build não estático sem DEPLOY_RUNTIME=serverless e com DEPLOY_RAND definido (no build estático o sufixo é vazio; no serverless o componente é trocado pelo Picture.runtime.astro). Mesmo assim, é justamente o caso em que o arquivo existe mas o tamanho não pôde ser lido, ou a imagem é remota, e a URL original funcionaria. Ajuste: usar ?V= quando o src não tem query string.
2. Teste deixa o console.warn mockado e não verifica o aviso (baixo)
Comentário na linha.
3. Aviso impreciso quando width e height são passados sem aspectRatio (nit, sem alteração)
Comentário na linha.
4. O build estático deixa de falhar com imagem inexistente (decisão a confirmar)
O build-prod.sh renderiza a home no passo estático com o Picture.astro. Antes, um banner apontando para um arquivo que não existe em public/ quebrava o build e o deploy não saía. Agora o deploy passa com um <img> quebrado e só um console.warn no log do build. A PR já descreve isso, e acho o comportamento novo melhor (uma referência errada não trava a loja inteira), mas vale a confirmação de quem mantém, porque o erro deixa de ser visível para o lojista.
| describe('SSR <picture> attributes', () => { | ||
| test('renders the original file when the image size is unknown', async () => { | ||
| // e.g. a new upload on CMS preview, not listed on the deployed images manifest | ||
| vi.spyOn(console, 'warn').mockImplementation(() => {}); |
There was a problem hiding this comment.
O spy do console.warn nunca é restaurado, então continua mockado no teste seguinte (e em qualquer outro que entrar neste arquivo), escondendo avisos reais. O teste também não verifica que o aviso foi emitido, que é a única pista que sobra no log quando o fallback acontece.
Ajuste: afterEach(() => vi.restoreAllMocks()) e um expect(warn).toHaveBeenCalledWith(expect.stringContaining('/img/uploads/new-banner.jpg')).
| // Unknown image size, e.g. a new CMS upload not deployed yet (CMS preview). | ||
| // `getPicture` would throw in the middle of the SSR stream and hang the response, | ||
| // so render the original file instead | ||
| console.warn(`Could not get size of image ${src}, rendering original file`); |
There was a problem hiding this comment.
Nit, sem alteração nesta PR: este else também pega quem passa width e height sem aspectRatio (linha 113 pula o tryImageSize nesse caso) e um aspectRatio inválido como "16/9" (vira NaN). Nos dois o aviso diz que não conseguiu ler o tamanho da imagem, o que não é a causa.
Antes esses casos lançavam erro, então ninguém depende deles e o fallback continua sendo melhor que o erro. Um follow-up razoável seria derivar o aspectRatio de width / height quando os dois são informados.
…thout optimization When the image size is unknown, `Picture.astro` now renders the original file, but still appended the `&V=` version suffix that assumes an `/_image?...` URL, producing `/img/banner.jpg&V=123`. Use `?V=` when the URL has no query string. Also restore the `console.warn` spy between tests and assert the fallback warning is logged. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
Ajustes da revisão aplicados em 750a46d: itens 1 (sufixo |
Problema
No painel de prévia do CMS, trocar a imagem de um banner por um upload novo derruba a prévia inteira com 504 (Gateway Timeout).
A prévia é renderizada pela função SSR que já está em produção (
/~preview/?content:...). A imagem nova ainda não consta doimages.src.csvdo deploy atual. Isso vale para upload não salvo, para rascunho salvo e até para os ~5 min de deploy depois de publicar. Sem as dimensões, ouseSSRPicturenão resolve oaspectRatio, e ogetPicturelança`aspectRatio` must be provided for remote images. O erro estoura no meio do stream do Astro (There was an uncaught error in the middle of the stream), e a resposta fica pendurada até o timeout do Cloud Run (10 s na loja onde reproduzi).Reproduzido numa loja em produção trocando o 1º slide do hero:
Could not match built … image).O código envolvido não muda desde 2024–2025, então não é regressão. O problema ficou visível porque o preview do PR do CMS estava falhando por outro motivo: sem ele, o lojista não tinha outro jeito de ver a imagem nova antes de publicar.
Solução
Quando não há como saber o tamanho da imagem, o
useSSRPicturenão chama mais ogetPicture. Ele renderiza o arquivo original (<img src>sem os<source>otimizados) e loga um aviso.getPictureé chamado exatamente como antes. SemaspectRatioele sempre lançava erro, então a mudança só troca esse erro pelo fallback.Picture.runtime.astro(SSR) ePicture.astro(build estático). No build estático, uma imagem referenciada que não existe empublic/deixa de derrubar a renderização da página e passa a sair como<img>quebrado, com o aviso no log.O que isso não resolve
getAsset). Isso fica para outra PR.serve-storefront). Qualquer outro componente que lance erro durante o SSR tem o mesmo efeito.Testes
packages/storefront/tests/ssr-picture.test.ts: com tamanho desconhecido, renderiza o original sem chamargetPicture; com tamanho conhecido, mantém as fontes otimizadas. O primeiro caso falha sem a correção, com o mesmo erro do log de produção.vitest runpassa 8/8. O ESLint com a config do storefront está limpo.🤖 Generated with Claude Code