summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorphyscik <mynameisgennadiy@vk.com>2026-04-14 21:50:53 +0500
committerphyscik <mynameisgennadiy@vk.com>2026-04-14 21:50:53 +0500
commit008de5f8a319f253ed5807160dc288855b1b6207 (patch)
tree4cedfc944c75464658609dd630a9f9d5b482c118 /backend
parenta0826ce054d7468444c67306191cc7e2fe734eb0 (diff)
Clearer error messages
Diffstat (limited to 'backend')
-rw-r--r--backend/src/API/ErrorDescription.zig4
-rw-r--r--backend/src/API/WeaponsAPI.zig41
-rw-r--r--backend/src/Database/RangedWeaponsAccessLayer.zig1
-rw-r--r--backend/src/Models/RangedWeapon.zig60
4 files changed, 79 insertions, 27 deletions
diff --git a/backend/src/API/ErrorDescription.zig b/backend/src/API/ErrorDescription.zig
index 922eb6f..76f420a 100644
--- a/backend/src/API/ErrorDescription.zig
+++ b/backend/src/API/ErrorDescription.zig
@@ -1,3 +1,7 @@
pub const ErrorDescriptor = struct {
Message: []const u8
};
+
+pub const NotFoundDescriptor = ErrorDescriptor {
+ .Message = "The requested object was not found"
+};
diff --git a/backend/src/API/WeaponsAPI.zig b/backend/src/API/WeaponsAPI.zig
index 1b0ae00..b9fd532 100644
--- a/backend/src/API/WeaponsAPI.zig
+++ b/backend/src/API/WeaponsAPI.zig
@@ -5,7 +5,6 @@ const db = @import("../Database/Connection.zig");
const errDesc = @import("ErrorDescription.zig");
pub fn RegisterEndpoints(router: *httpz.Router(void, *const fn (*httpz.request.Request, *httpz.response.Response) anyerror!void)) void {
- router.get("/weapons", testEndpoint, .{});
router.get("/weapons/ranged", getAllRangedWeapons, .{});
router.post("/weapons/ranged", newRangedWeapon, .{});
router.get("/weapons/ranged/:id", getRangedWeaponById, .{});
@@ -13,27 +12,6 @@ pub fn RegisterEndpoints(router: *httpz.Router(void, *const fn (*httpz.request.R
router.delete("/weapons/ranged/:id", deleteRangedWeapon, .{});
}
-fn testEndpoint(_: *httpz.Request, res: *httpz.Response) !void {
- const testType: model.RangedWeaponType = .{
- .Id = "any",
- .Name = "BudgetArms C-13",
- .WeaponType = "P",
- .Accuracy = -1,
- .Concealability = "P",
- .Avaliability = "E",
- .Damage = "1D6",
- .Ammunition = "5mm",
- .NumberOfShots = 8,
- .RateOfFire = 2,
- .Reliability = "ST",
- .CreatedAt = 0,
- .UpdatedAt = 0,
- };
-
- res.status = 200;
- try res.json(testType, .{});
-}
-
fn getAllRangedWeapons(req: *httpz.Request, res: *httpz.Response) !void {
var found = try db.RangedWeapons.GetAll(req.arena);
defer found.deinit(req.arena);
@@ -51,6 +29,7 @@ fn getRangedWeaponById(req: *httpz.Request, res: *httpz.Response) !void {
// Empty result handling
if (err == db.ResultErrors.NotFound) {
res.status = 204;
+ try res.json(errDesc.NotFoundDescriptor, .{});
return;
}
return err;
@@ -60,12 +39,13 @@ fn getRangedWeaponById(req: *httpz.Request, res: *httpz.Response) !void {
}
fn newRangedWeapon(req: *httpz.Request, res: *httpz.Response) !void {
- var body = try req.json(model.RangedWeaponType) orelse {
+ var body = try req.json(model.RequestBody) orelse {
res.status = 400;
return;
};
- db.RangedWeapons.Create(&body) catch |err| {
+ var weapon = body.ToModel();
+ db.RangedWeapons.Create(&weapon) catch |err| {
if (err == db.ResultErrors.AlreadyExists) {
res.status = 400;
try res.json(errDesc.ErrorDescriptor {
@@ -79,19 +59,26 @@ fn newRangedWeapon(req: *httpz.Request, res: *httpz.Response) !void {
res.status = 201;
}
-
fn updateRangedWeapon(req: *httpz.Request, res: *httpz.Response) !void {
const id = req.param("id") orelse {
res.status = 400;
return;
};
- var body = try req.json(model.RangedWeaponType) orelse {
+ var body = try req.json(model.RequestBody) orelse {
res.status = 400;
return;
};
- try db.RangedWeapons.Update(id, &body);
+ var weapon = body.ToModel();
+ db.RangedWeapons.Update(id, &weapon) catch |err| {
+ if (err == db.ResultErrors.NotFound) {
+ res.status = 204;
+ try res.json(errDesc.NotFoundDescriptor, .{});
+ return;
+ }
+ return err;
+ };
}
fn deleteRangedWeapon(req: *httpz.Request, res: *httpz.Response) !void {
diff --git a/backend/src/Database/RangedWeaponsAccessLayer.zig b/backend/src/Database/RangedWeaponsAccessLayer.zig
index ff75244..8d86840 100644
--- a/backend/src/Database/RangedWeaponsAccessLayer.zig
+++ b/backend/src/Database/RangedWeaponsAccessLayer.zig
@@ -31,6 +31,7 @@ pub fn GetByDisplayName(allocator: std.mem.Allocator, displayName: []const u8) !
}
pub fn Update(displayName: []const u8, updatedModel: *model.RangedWeaponType) !void {
+ if (!try Exists(displayName)) return conn.ResultErrors.NotFound;
const query =
\\ UPDATE RangedWeapons SET
\\ id = $1,
diff --git a/backend/src/Models/RangedWeapon.zig b/backend/src/Models/RangedWeapon.zig
index 3864fc5..b2c15cd 100644
--- a/backend/src/Models/RangedWeapon.zig
+++ b/backend/src/Models/RangedWeapon.zig
@@ -77,6 +77,41 @@ pub const RangedWeaponType = struct {
};
+
+// The full model is causing error.MissingFields if we don't specify readonly
+// CreatedAt and UpdatedAt fields
+pub const RequestBody = struct {
+ Id: []const u8,
+ Name: []const u8,
+ WeaponType: []const u8,
+ Accuracy: i32,
+ Concealability: []const u8,
+ Avaliability: []const u8,
+ Damage: []const u8,
+ Ammunition: []const u8,
+ NumberOfShots: u31,
+ RateOfFire: u32,
+ Reliability: []const u8,
+
+ pub fn ToModel(this: RequestBody) RangedWeaponType {
+ return RangedWeaponType {
+ .Id = this.Id,
+ .Name = this.Name,
+ .WeaponType = this.WeaponType,
+ .Accuracy = this.Accuracy,
+ .Concealability = this.Concealability,
+ .Avaliability = this.Avaliability,
+ .Damage = this.Damage,
+ .Ammunition = this.Ammunition,
+ .NumberOfShots = this.NumberOfShots,
+ .RateOfFire = this.RateOfFire,
+ .Reliability = this.Reliability,
+ .CreatedAt = 0,
+ .UpdatedAt = 0
+ };
+ }
+};
+
// ==================== tests ====================
fn getTestType() RangedWeaponType {
@@ -104,3 +139,28 @@ test "CompactNotation" {
"P/-1/P/E/1D6(5mm)/8/2/ST",
try testType.GetCompactNotation('/'));
}
+
+test "Request to model" {
+ var req: RequestBody = .{
+ .Id = "any",
+ .Name = "any",
+ .WeaponType = "P",
+ .Accuracy = -1,
+ .Concealability = "P",
+ .Avaliability = "E",
+ .Damage = "1D6",
+ .Ammunition = "5mm",
+ .NumberOfShots = 8,
+ .RateOfFire = 2,
+ .Reliability = "ST",
+ };
+
+ const expected = getTestType();
+ const result = req.ToModel();
+
+ try std.testing.expectEqualStrings(expected.Id, result.Id);
+ try std.testing.expectEqualStrings(expected.Name, result.Name);
+ try std.testing.expectEqual(expected.Accuracy, result.Accuracy);
+ try std.testing.expectEqual(0, result.CreatedAt);
+ try std.testing.expectEqual(0, result.UpdatedAt);
+}