fullstackhero/dotnet-starter-kit · error · NotFoundException
Product not found.
Error message
Product {command.ProductId} not found. What it means
ReorderProductImagesCommandHandler loads the product for command.ProductId and throws NotFoundException when no matching product exists (HTTP 404), before delegating to product.ReorderImages. The product must exist and be visible under current query filters (tenant, not soft-deleted).
Solutions
- Re-fetch the product before submitting reorder state; if 404, redirect back to the list.
- Catch the 404 and surface 'this product no longer exists' instead of a raw error.
- Ensure the OrderedImageIds array belongs to the same product as ProductId.
- Verify tenant context and that the product is not soft-deleted.
Example fix
// before
await api.reorderProductImages(productId, orderedIds);
// after
try {
await api.reorderProductImages(productId, orderedIds);
} catch (e) {
if (e.status === 404) {
notify('Product no longer exists');
navigate('/products');
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const product = await api.getProduct(productId).catch(() => null);
if (!product) { navigate('/products'); return; } Try / catch
try {
await api.reorderProductImages(productId, orderedIds);
} catch (e) {
if (e.status === 404) {
notify('Product no longer exists');
navigate('/products');
return;
}
throw e;
} Prevention
- Block reorder submission when the editor's product data is stale
- Close/redirect editors whose product was deleted elsewhere
- Ensure ordered image ids originate from the same product fetch
When it happens
Trigger: Reorder call with a nonexistent/soft-deleted/other-tenant ProductId, or a drag-and-drop submit fired after the product was deleted in another tab/session.
Common situations: Stale editor page submitting a reorder after the product was deleted elsewhere; ids from a different tenant/environment; retrying a reorder whose product was removed meanwhile.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/1170b362c2e06bca.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Catalog/Modules.Catalog/Features/v1/Products/ReorderProductImages/ReorderProductImagesCommandHandler.cs:19
using FSH.Framework.Core.Exceptions;
using FSH.Modules.Catalog.Contracts.v1.Products.ReorderProductImages;
using FSH.Modules.Catalog.Data;
using Mediator;
using Microsoft.EntityFrameworkCore;
namespace FSH.Modules.Catalog.Features.v1.Products.ReorderProductImages;
public sealed class ReorderProductImagesCommandHandler(CatalogDbContext dbContext)
: ICommandHandler<ReorderProductImagesCommand, Unit>
{
public async ValueTask<Unit> Handle(ReorderProductImagesCommand command, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(command);
var product = await dbContext.Products
.FirstOrDefaultAsync(p => p.Id == command.ProductId, cancellationToken)
.ConfigureAwait(false)
?? throw new NotFoundException($"Product {command.ProductId} not found.");
product.ReorderImages(command.OrderedImageIds);
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return Unit.Value;
}
}
View on GitHub (pinned to 3f2959e683)