An AI assistant wrote the label route, the text for the shop's shelf: GET /products/1/label answers {"label": "Mug (kitchen)"}. It put its code in a try, which is a good idea: when something fails, the route still answers. But look at what its catch sends back:
app.MapGet("/products/{id}/label", (int id, HttpRequest request) => {
var sql = "SELECT name, category FROM products WHERE id = $id";
try {
var cmd = db.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("$id", id);
using var row = cmd.ExecuteReader();
row.Read();
var label = row.GetString(0) + " (" + row.GetString(1) + ")";
return Results.Json(new { label = label });
} catch (Exception error) {
return Results.Json(new { error = error.Message, sql = sql, trace = error.StackTrace }, statusCode: 500);
}
});
That answer goes to whoever made the request. It holds the error's text, the SQL query and the stack trace: the methods, files and lines of code that led to the crash. A customer can't do anything with it. An attacker can: table names, column names and your code are a free map for finding the next hole.
The rule: the details go to the log, which only you read, and the visitor gets a short safe message. Here it is on another route:
} catch (Exception error) {
app.Logger.LogError("order {Id} failed: {Message}", orderId, error.Message);
return Results.Json(new { error = "Please try again later" }, statusCode: 500);
}
A missing product is not a server error, so it answers 404, not 500. Your rewrite must give these answers (product 8 is a Gift card with no category, a bug nobody had found yet):
GET /products/1/label → 200 {"label": "Mug (kitchen)"}
GET /products/6/label → 200 {"label": "Teapot (kitchen)"}
GET /products/8/label → 500 {"error": "Something went wrong on our side"}
GET /products/99/label → 404 {"error": "Product not found"}
The check then reads your log through /_test/log, a route it adds only for the test, and expects one line: ERROR GET /products/8/label failed: The data is NULL at ordinal 1. This method can't be called on NULL values. Check using IsDBNull before calling.
Your task: rewrite the body of the label route's MapGet function so any error answers only {"error": "Something went wrong on our side"} with 500 and logs the method, the path and the error, while a missing product answers 404.
Assignment
Follow the Coding Tutorial to rewrite the label route with a try that builds the label and a catch that logs the details and answers a safe message.
Hint
The catch comes right after the try's closing brace: } catch (Exception error) {. The 404 check sits inside the try, right below the row line: row.Read() gives false when there is no row. Pass app.Logger.LogError the text "{Method} {Path} failed: {Message}", then the three values in order.
Free plan: 30 tutor messages. PRO is unlimited.
