better error treatment#161
Conversation
|
Warning Review limit reached
Next review available in: 38 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. 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, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (15)
📝 WalkthroughWalkthroughEl PR reemplaza enlaces internos por ChangesFlujos de navegación interna
Errores de autenticación
Errores y reintento de producto
Perfil y carrito
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ProfilePage
participant getServerSession
participant UserRepository
participant ProfileForm
participant UsersAPI
ProfilePage->>getServerSession: Obtener sesión
ProfilePage->>UserRepository: Buscar usuario
UserRepository-->>ProfilePage: Devolver perfil
ProfilePage->>ProfileForm: Pasar datos del perfil
ProfileForm->>UsersAPI: PATCH /api/users/me
ProfileForm->>UsersAPI: DELETE /api/users/me
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
app/[locale]/products/[id]/error.module.css (1)
6-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueActualizar la notación de colores a sintaxis moderna.
Las herramientas de análisis estático (Stylelint) sugieren actualizar la notación de
rgba()a la sintaxis moderna dergb()con porcentajes para el canal alfa. Esto mejora la consistencia y cumple con los estándares actuales de CSS.♻️ Propuesta de refactorización
Reemplazar el uso de
rgbaen el degradado de fondo:- background: - radial-gradient( - circle at 12% 18%, - rgba(213, 92, 92, 0.12), - transparent 24rem - ), - linear-gradient( - 135deg, - rgba(247, 241, 232, 0.72), - rgba(255, 255, 255, 0.94) - ); + background: + radial-gradient( + circle at 12% 18%, + rgb(213 92 92 / 12%), + transparent 24rem + ), + linear-gradient( + 135deg, + rgb(247 241 232 / 72%), + rgb(255 255 255 / 94%) + );Reemplazar los colores en el contenedor de la tarjeta (
.card):- border: 1px solid rgba(13, 92, 70, 0.16); + border: 1px solid rgb(13 92 70 / 16%); border-top: 5px solid var(--color-coral); border-radius: var(--radius-md); padding: clamp(2rem, 7vw, 4.5rem); background: var(--color-white); - box-shadow: 0 1.5rem 4rem rgba(8, 20, 18, 0.1); + box-shadow: 0 1.5rem 4rem rgb(8 20 18 / 10%);Y finalmente el estado focus-visible del botón:
.retry:focus-visible { - outline: 3px solid rgba(213, 92, 92, 0.48); + outline: 3px solid rgb(213 92 92 / 48%); outline-offset: 3px; }Also applies to: 21-26, 68-71
🤖 Prompt for 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. In `@app/`[locale]/products/[id]/error.module.css around lines 6 - 16, Actualiza las declaraciones de color en el fondo del módulo, el contenedor .card y el estado focus-visible del botón, reemplazando todas las formas rgba() por la sintaxis moderna rgb() con el canal alfa expresado como porcentaje. Conserva exactamente los mismos valores visuales y gradientes.Source: Linters/SAST tools
modules/cart/presentation/components/cart-view.tsx (1)
311-327: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueEvita llamadas duplicadas a
buildCustomizationHref.Se está llamando a la función
buildCustomizationHrefdos veces consecutivas con los mismos argumentos en este render. Puedes utilizar una función anónima autoejecutable (IIFE) para calcular el resultado una sola vez.♻️ Refactor sugerido
- {labels.customizationEditFromCart && - buildCustomizationHref( - locale, - item.productId, - item.customization, - item.id, - ) && ( - <Link - href={ - buildCustomizationHref( - locale, - item.productId, - item.customization, - item.id, - ) ?? '#' - } - className={styles.editLink} - > - {labels.customizationEditFromCart} - </Link> - )} + {(() => { + const editHref = buildCustomizationHref( + locale, + item.productId, + item.customization, + item.id, + ); + return labels.customizationEditFromCart && editHref ? ( + <Link href={editHref} className={styles.editLink}> + {labels.customizationEditFromCart} + </Link> + ) : null; + })()}🤖 Prompt for 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. In `@modules/cart/presentation/components/cart-view.tsx` around lines 311 - 327, Actualiza el render alrededor de buildCustomizationHref para calcular el enlace una sola vez por elemento, reutilizando ese resultado tanto en la condición como en la prop href del componente Link. Puedes encapsular la evaluación en una IIFE, manteniendo el comportamiento actual y el fallback a '#' cuando no haya URL.
🤖 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 `@app/`[locale]/profile/page.tsx:
- Around line 3-4: Modifica ProfilePage para que no consulte directamente el
repositorio: introduce un caso de uso de aplicación como GetUserProfileUseCase,
define la interfaz de puerto necesaria en la capa de dominio/aplicación y mueve
la implementación concreta al adaptador de infraestructura. Registra y resuelve
el caso de uso mediante container en el composition root, haciendo que la página
dependa únicamente de ese caso de uso y conserve el comportamiento actual del
perfil.
In `@app/`[locale]/profile/profile-form.tsx:
- Around line 45-58: Update the address handling in the profile form so clearing
every address field sends an explicit deletion value instead of omitting address
from the PATCH. Preserve omission when the user made no address change, and
update the corresponding request schema/API handling to distinguish “unchanged”
from “delete” while retaining normal address updates.
In `@modules/cart/presentation/components/cart-view.tsx`:
- Around line 229-236: Actualiza el enlace del botón `ctaButton` en el
componente de vista del carrito para construir la ruta con `locale` sin la barra
final, de modo que genere `'/es'` en lugar de `'/es/'`; conserva intactos el
texto `labels.browseProducts` y el resto de la navegación.
In `@tests/unit/app/`[locale]/profile/profile-form.test.tsx:
- Around line 40-72: Amplía las pruebas de ProfileForm alrededor de las
mutaciones PATCH y DELETE para comprobar que, cuando la respuesta falla, se
muestra el mensaje de error y termina el estado de carga. Añade también un caso
que vacíe completamente la dirección y verifique el payload o comportamiento
esperado para valores vacíos. Conserva las aserciones existentes sobre los
métodos PATCH y DELETE en mockFetch.
---
Nitpick comments:
In `@app/`[locale]/products/[id]/error.module.css:
- Around line 6-16: Actualiza las declaraciones de color en el fondo del módulo,
el contenedor .card y el estado focus-visible del botón, reemplazando todas las
formas rgba() por la sintaxis moderna rgb() con el canal alfa expresado como
porcentaje. Conserva exactamente los mismos valores visuales y gradientes.
In `@modules/cart/presentation/components/cart-view.tsx`:
- Around line 311-327: Actualiza el render alrededor de buildCustomizationHref
para calcular el enlace una sola vez por elemento, reutilizando ese resultado
tanto en la condición como en la prop href del componente Link. Puedes
encapsular la evaluación en una IIFE, manteniendo el comportamiento actual y el
fallback a '#' cuando no haya URL.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e04a3e6b-036b-41fa-8bd0-fe19f134e7c2
📒 Files selected for processing (29)
app/[locale]/admin/sellers/page.tsxapp/[locale]/auth/signin/page.tsxapp/[locale]/auth/signup/page.tsxapp/[locale]/layout.tsxapp/[locale]/orders/page.tsxapp/[locale]/products/[id]/customization-experience.tsxapp/[locale]/products/[id]/error.module.cssapp/[locale]/products/[id]/error.tsxapp/[locale]/products/[id]/page.tsxapp/[locale]/profile/page.tsxapp/[locale]/profile/profile-form.tsxapp/[locale]/seller/orders/page.tsxapp/[locale]/seller/products/page.tsxmodules/cart/presentation/components/cart-view.tsxmodules/products/application/get-product-by-id-use-case.tsshared/i18n/locales/cat.jsonshared/i18n/locales/es.jsonshared/layout/header-nav.tsxshared/layout/login-modal.tsxshared/ui/pagination.tsxtests/unit/app/[locale]/auth/signin/signin-page.test.tsxtests/unit/app/[locale]/products/[id]/customization-experience.test.tsxtests/unit/app/[locale]/products/[id]/error.test.tsxtests/unit/app/[locale]/products/[id]/page.test.tsxtests/unit/app/[locale]/profile/profile-form.test.tsxtests/unit/app/[locale]/profile/profile-page.test.tsxtests/unit/app/cart/cart-view.test.tsxtests/unit/modules/presentation/components/login-modal.test.tsxtests/unit/modules/products/application/get-product-by-id-use-case.test.ts
| <div className={styles.empty}> | ||
| <h2>{labels.emptyTitle}</h2> | ||
| <p>{labels.emptyDescription}</p> | ||
| <a href={`/${locale}/`} className={styles.ctaButton}> | ||
| <Link href={`/${locale}/`} className={styles.ctaButton}> | ||
| {labels.browseProducts} | ||
| </a> | ||
| </Link> | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Elimina la barra final (trailing slash) para alinear el enlace con las pruebas.
El test unitario en cart-view.test.tsx fue actualizado en este PR para esperar '/es' en lugar de '/es/'. Mantener la barra final aquí causará que la aserción del test falle, además de generar inconsistencias con la navegación del logo en el layout principal.
🐛 Fix sugerido
- <Link href={`/${locale}/`} className={styles.ctaButton}>
+ <Link href={`/${locale}`} className={styles.ctaButton}>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className={styles.empty}> | |
| <h2>{labels.emptyTitle}</h2> | |
| <p>{labels.emptyDescription}</p> | |
| <a href={`/${locale}/`} className={styles.ctaButton}> | |
| <Link href={`/${locale}/`} className={styles.ctaButton}> | |
| {labels.browseProducts} | |
| </a> | |
| </Link> | |
| </div> | |
| ); | |
| <div className={styles.empty}> | |
| <h2>{labels.emptyTitle}</h2> | |
| <p>{labels.emptyDescription}</p> | |
| <Link href={`/${locale}`} className={styles.ctaButton}> | |
| {labels.browseProducts} | |
| </Link> | |
| </div> | |
| ); |
🤖 Prompt for 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.
In `@modules/cart/presentation/components/cart-view.tsx` around lines 229 - 236,
Actualiza el enlace del botón `ctaButton` en el componente de vista del carrito
para construir la ruta con `locale` sin la barra final, de modo que genere
`'/es'` en lugar de `'/es/'`; conserva intactos el texto `labels.browseProducts`
y el resto de la navegación.
| it('preserves profile PATCH mutations', async () => { | ||
| const user = userEvent.setup(); | ||
| mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({}) }); | ||
| render(<ProfileForm locale="es" profile={profile} role="CUSTOMER" />); | ||
|
|
||
| await user.clear(screen.getByLabelText('Nombre')); | ||
| await user.type(screen.getByLabelText('Nombre'), 'Jane'); | ||
| await user.click(screen.getByRole('button', { name: 'Enviar' })); | ||
|
|
||
| expect(mockFetch).toHaveBeenCalledWith('/api/users/me', { | ||
| method: 'PATCH', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| body: expect.stringContaining('"firstName":"Jane"'), | ||
| }); | ||
| }); | ||
|
|
||
| it('preserves profile DELETE mutations', async () => { | ||
| const user = userEvent.setup(); | ||
| mockFetch.mockResolvedValueOnce({ | ||
| ok: false, | ||
| json: async () => ({ error: 'Failed to delete account' }), | ||
| }); | ||
| render(<ProfileForm locale="es" profile={profile} role="CUSTOMER" />); | ||
|
|
||
| await user.click(screen.getByRole('button', { name: 'Eliminar cuenta' })); | ||
| await user.click( | ||
| screen.getAllByRole('button', { name: 'Eliminar cuenta' })[1], | ||
| ); | ||
|
|
||
| expect(mockFetch).toHaveBeenCalledWith('/api/users/me', { | ||
| method: 'DELETE', | ||
| }); | ||
| }); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Completa las pruebas de errores y estados vacíos.
Añade casos que verifiquen el mensaje y el fin de la carga tras fallos de PATCH/DELETE, además del comportamiento al vaciar completamente la dirección. El test de DELETE actual seguiría pasando aunque el error dejara de mostrarse.
As per coding guidelines: «Write tests before implementing business logic, including empty states, invalid inputs, error conditions, and fakes or mocks for infrastructure dependencies.»
🤖 Prompt for 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.
In `@tests/unit/app/`[locale]/profile/profile-form.test.tsx around lines 40 - 72,
Amplía las pruebas de ProfileForm alrededor de las mutaciones PATCH y DELETE
para comprobar que, cuando la respuesta falla, se muestra el mensaje de error y
termina el estado de carga. Añade también un caso que vacíe completamente la
dirección y verifique el payload o comportamiento esperado para valores vacíos.
Conserva las aserciones existentes sobre los métodos PATCH y DELETE en
mockFetch.
Source: Coding guidelines
Summary by CodeRabbit
Nuevas funcionalidades
Correcciones