diff --git a/examples/accept/accept.zig b/examples/accept/accept.zig
index 55c9b53..a9e268c 100644
--- a/examples/accept/accept.zig
+++ b/examples/accept/accept.zig
@@ -5,7 +5,7 @@ var gpa = std.heap.GeneralPurposeAllocator(.{
.thread_safe = true,
}){};
-fn on_request_verbose(r: zap.Request) void {
+fn on_request_verbose(r: zap.Request) !void {
// use a local buffer for the parsed accept headers
var accept_buffer: [1024]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&accept_buffer);
@@ -21,38 +21,38 @@ fn on_request_verbose(r: zap.Request) void {
break :content_type .HTML;
};
- r.setContentType(content_type) catch return;
+ try r.setContentType(content_type);
switch (content_type) {
.TEXT => {
- r.sendBody("Hello from ZAP!!!") catch return;
+ try r.sendBody("Hello from ZAP!!!");
},
.HTML => {
- r.sendBody("
Hello from ZAP!!!
") catch return;
+ try r.sendBody("Hello from ZAP!!!
");
},
.XML => {
- r.sendBody(
+ try r.sendBody(
\\
\\
\\
\\ Hello from ZAP!!!
\\
\\
- ) catch return;
+ );
},
.JSON => {
var buffer: [128]u8 = undefined;
- const json = zap.util.stringifyBuf(&buffer, .{ .message = "Hello from ZAP!!!" }, .{}) orelse return;
- r.sendJson(json) catch return;
+ const json = try zap.util.stringifyBuf(&buffer, .{ .message = "Hello from ZAP!!!" }, .{});
+ try r.sendJson(json);
},
.XHTML => {
- r.sendBody(
+ try r.sendBody(
\\
\\
\\
\\ Hello from ZAP!!!
\\
\\
- ) catch return;
+ );
},
}
}
diff --git a/examples/bindataformpost/bindataformpost.zig b/examples/bindataformpost/bindataformpost.zig
index 4c2c7ad..9cc0eda 100644
--- a/examples/bindataformpost/bindataformpost.zig
+++ b/examples/bindataformpost/bindataformpost.zig
@@ -4,7 +4,7 @@ const zap = @import("zap");
const Handler = struct {
var alloc: std.mem.Allocator = undefined;
- pub fn on_request(r: zap.Request) void {
+ pub fn on_request(r: zap.Request) !void {
// parse for FORM (body) parameters first
r.parseBody() catch |err| {
std.log.err("Parse Body error: {any}. Expected if body is empty", .{err});
@@ -24,7 +24,7 @@ const Handler = struct {
//
// HERE WE HANDLE THE BINARY FILE
//
- const params = r.parametersToOwnedList(Handler.alloc, false) catch unreachable;
+ const params = try r.parametersToOwnedList(Handler.alloc, false);
defer params.deinit();
for (params.items) |kv| {
if (kv.value) |v| {
@@ -82,7 +82,7 @@ const Handler = struct {
} else |err| {
std.log.err("cannot check for terminate param: {any}\n", .{err});
}
- r.sendJson("{ \"ok\": true }") catch unreachable;
+ try r.sendJson("{ \"ok\": true }");
}
};
diff --git a/examples/cookies/cookies.zig b/examples/cookies/cookies.zig
index 087731f..16fc9a8 100644
--- a/examples/cookies/cookies.zig
+++ b/examples/cookies/cookies.zig
@@ -35,7 +35,7 @@ pub fn main() !void {
const Handler = struct {
var alloc: std.mem.Allocator = undefined;
- pub fn on_request(r: zap.Request) void {
+ pub fn on_request(r: zap.Request) !void {
std.debug.print("\n=====================================================\n", .{});
defer std.debug.print("=====================================================\n\n", .{});
diff --git a/examples/endpoint/main.zig b/examples/endpoint/main.zig
index d6b519b..a38803a 100644
--- a/examples/endpoint/main.zig
+++ b/examples/endpoint/main.zig
@@ -4,12 +4,12 @@ const UserWeb = @import("userweb.zig");
const StopEndpoint = @import("stopendpoint.zig");
// this is just to demo that we can catch arbitrary slugs as fallback
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
if (r.path) |the_path| {
std.debug.print("REQUESTED PATH: {s}\n", .{the_path});
}
- r.sendBody("Hello from ZAP!!!
") catch return;
+ try r.sendBody("Hello from ZAP!!!
");
}
pub fn main() !void {
diff --git a/examples/endpoint/stopendpoint.zig b/examples/endpoint/stopendpoint.zig
index b9a7c46..d0e0a12 100644
--- a/examples/endpoint/stopendpoint.zig
+++ b/examples/endpoint/stopendpoint.zig
@@ -6,6 +6,7 @@ const zap = @import("zap");
pub const Self = @This();
path: []const u8,
+error_strategy: zap.Endpoint.ErrorStrategy = .log_to_response,
pub fn init(path: []const u8) Self {
return .{
@@ -13,14 +14,14 @@ pub fn init(path: []const u8) Self {
};
}
-pub fn get(e: *Self, r: zap.Request) void {
+pub fn get(e: *Self, r: zap.Request) anyerror!void {
_ = e;
_ = r;
zap.stop();
}
-pub fn post(_: *Self, _: zap.Request) void {}
-pub fn put(_: *Self, _: zap.Request) void {}
-pub fn delete(_: *Self, _: zap.Request) void {}
-pub fn patch(_: *Self, _: zap.Request) void {}
-pub fn options(_: *Self, _: zap.Request) void {}
+pub fn post(_: *Self, _: zap.Request) anyerror!void {}
+pub fn put(_: *Self, _: zap.Request) anyerror!void {}
+pub fn delete(_: *Self, _: zap.Request) anyerror!void {}
+pub fn patch(_: *Self, _: zap.Request) anyerror!void {}
+pub fn options(_: *Self, _: zap.Request) anyerror!void {}
diff --git a/examples/endpoint/userweb.zig b/examples/endpoint/userweb.zig
index 31cc587..e492408 100644
--- a/examples/endpoint/userweb.zig
+++ b/examples/endpoint/userweb.zig
@@ -11,6 +11,7 @@ alloc: std.mem.Allocator = undefined,
_users: Users = undefined,
path: []const u8,
+error_strategy: zap.Endpoint.ErrorStrategy = .log_to_response,
pub fn init(
a: std.mem.Allocator,
@@ -42,8 +43,8 @@ fn userIdFromPath(self: *Self, path: []const u8) ?usize {
return null;
}
-pub fn put(_: *Self, _: zap.Request) void {}
-pub fn get(self: *Self, r: zap.Request) void {
+pub fn put(_: *Self, _: zap.Request) anyerror!void {}
+pub fn get(self: *Self, r: zap.Request) anyerror!void {
if (r.path) |path| {
// /users
if (path.len == self.path.len) {
@@ -52,33 +53,31 @@ pub fn get(self: *Self, r: zap.Request) void {
var jsonbuf: [256]u8 = undefined;
if (self.userIdFromPath(path)) |id| {
if (self._users.get(id)) |user| {
- if (zap.util.stringifyBuf(&jsonbuf, user, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, user, .{});
+ try r.sendJson(json);
}
}
}
}
-fn listUsers(self: *Self, r: zap.Request) void {
+fn listUsers(self: *Self, r: zap.Request) !void {
if (self._users.toJSON()) |json| {
defer self.alloc.free(json);
- r.sendJson(json) catch return;
+ try r.sendJson(json);
} else |err| {
- std.debug.print("LIST error: {}\n", .{err});
+ return err;
}
}
-pub fn post(self: *Self, r: zap.Request) void {
+pub fn post(self: *Self, r: zap.Request) anyerror!void {
if (r.body) |body| {
const maybe_user: ?std.json.Parsed(User) = std.json.parseFromSlice(User, self.alloc, body, .{}) catch null;
if (maybe_user) |u| {
defer u.deinit();
if (self._users.addByName(u.value.first_name, u.value.last_name)) |id| {
var jsonbuf: [128]u8 = undefined;
- if (zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
+ try r.sendJson(json);
} else |err| {
std.debug.print("ADDING error: {}\n", .{err});
return;
@@ -87,7 +86,7 @@ pub fn post(self: *Self, r: zap.Request) void {
}
}
-pub fn patch(self: *Self, r: zap.Request) void {
+pub fn patch(self: *Self, r: zap.Request) anyerror!void {
if (r.path) |path| {
if (self.userIdFromPath(path)) |id| {
if (self._users.get(id)) |_| {
@@ -97,13 +96,11 @@ pub fn patch(self: *Self, r: zap.Request) void {
defer u.deinit();
var jsonbuf: [128]u8 = undefined;
if (self._users.update(id, u.value.first_name, u.value.last_name)) {
- if (zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
+ try r.sendJson(json);
} else {
- if (zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{});
+ try r.sendJson(json);
}
}
}
@@ -112,26 +109,24 @@ pub fn patch(self: *Self, r: zap.Request) void {
}
}
-pub fn delete(self: *Self, r: zap.Request) void {
+pub fn delete(self: *Self, r: zap.Request) anyerror!void {
if (r.path) |path| {
if (self.userIdFromPath(path)) |id| {
var jsonbuf: [128]u8 = undefined;
if (self._users.delete(id)) {
- if (zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
+ try r.sendJson(json);
} else {
- if (zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{})) |json| {
- r.sendJson(json) catch return;
- }
+ const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{});
+ try r.sendJson(json);
}
}
}
}
-pub fn options(_: *Self, r: zap.Request) void {
- r.setHeader("Access-Control-Allow-Origin", "*") catch return;
- r.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") catch return;
+pub fn options(_: *Self, r: zap.Request) anyerror!void {
+ try r.setHeader("Access-Control-Allow-Origin", "*");
+ try r.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
r.setStatus(zap.http.StatusCode.no_content);
r.markAsFinished(true);
}
diff --git a/examples/endpoint_auth/endpoint_auth.zig b/examples/endpoint_auth/endpoint_auth.zig
index f6f1e8a..57b2a37 100644
--- a/examples/endpoint_auth/endpoint_auth.zig
+++ b/examples/endpoint_auth/endpoint_auth.zig
@@ -13,24 +13,25 @@ const HTTP_RESPONSE: []const u8 =
const Endpoint = struct {
// the slug
path: []const u8,
+ error_strategy: zap.Endpoint.ErrorStrategy = .log_to_response,
// authenticated requests go here
- pub fn get(_: *Endpoint, r: zap.Request) void {
+ pub fn get(_: *Endpoint, r: zap.Request) !void {
r.sendBody(HTTP_RESPONSE) catch return;
}
// just for fun, we also catch the unauthorized callback
- pub fn unauthorized(_: *Endpoint, r: zap.Request) void {
+ pub fn unauthorized(_: *Endpoint, r: zap.Request) !void {
r.setStatus(.unauthorized);
r.sendBody("UNAUTHORIZED ACCESS") catch return;
}
// not implemented, don't care
- pub fn post(_: *Endpoint, _: zap.Request) void {}
- pub fn put(_: *Endpoint, _: zap.Request) void {}
- pub fn delete(_: *Endpoint, _: zap.Request) void {}
- pub fn patch(_: *Endpoint, _: zap.Request) void {}
- pub fn options(_: *Endpoint, _: zap.Request) void {}
+ pub fn post(_: *Endpoint, _: zap.Request) !void {}
+ pub fn put(_: *Endpoint, _: zap.Request) !void {}
+ pub fn delete(_: *Endpoint, _: zap.Request) !void {}
+ pub fn patch(_: *Endpoint, _: zap.Request) !void {}
+ pub fn options(_: *Endpoint, _: zap.Request) !void {}
};
pub fn main() !void {
diff --git a/examples/hello/hello.zig b/examples/hello/hello.zig
index 8b0f760..c7db536 100644
--- a/examples/hello/hello.zig
+++ b/examples/hello/hello.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request_verbose(r: zap.Request) void {
+fn on_request_verbose(r: zap.Request) !void {
if (r.path) |the_path| {
std.debug.print("PATH: {s}\n", .{the_path});
}
@@ -9,11 +9,11 @@ fn on_request_verbose(r: zap.Request) void {
if (r.query) |the_query| {
std.debug.print("QUERY: {s}\n", .{the_query});
}
- r.sendBody("Hello from ZAP!!!
") catch return;
+ try r.sendBody("Hello from ZAP!!!
");
}
-fn on_request_minimal(r: zap.Request) void {
- r.sendBody("Hello from ZAP!!!
") catch return;
+fn on_request_minimal(r: zap.Request) !void {
+ try r.sendBody("Hello from ZAP!!!
");
}
pub fn main() !void {
diff --git a/examples/hello2/hello2.zig b/examples/hello2/hello2.zig
index 4f43a5e..51e8faa 100644
--- a/examples/hello2/hello2.zig
+++ b/examples/hello2/hello2.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
const m = r.methodAsEnum();
const m_str = r.method orelse "";
const p = r.path orelse "/";
@@ -20,8 +20,8 @@ fn on_request(r: zap.Request) void {
std.debug.print(">> BODY: {s}\n", .{the_body});
}
- r.setContentTypeFromPath() catch return;
- r.sendBody(
+ try r.setContentTypeFromPath();
+ try r.sendBody(
\\
\\ Hello from ZAP!!!
\\
\\
- ) catch return;
+ );
}
pub fn main() !void {
diff --git a/examples/hello_json/hello_json.zig b/examples/hello_json/hello_json.zig
index 56c5cd8..21f9f46 100644
--- a/examples/hello_json/hello_json.zig
+++ b/examples/hello_json/hello_json.zig
@@ -6,7 +6,7 @@ const User = struct {
last_name: ?[]const u8 = null,
};
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
if (r.methodAsEnum() != .GET) return;
// /user/n
@@ -14,16 +14,16 @@ fn on_request(r: zap.Request) void {
if (the_path.len < 7 or !std.mem.startsWith(u8, the_path, "/user/"))
return;
- const user_id: usize = @as(usize, @intCast(the_path[6] - 0x30));
+ const user_id: usize = @intCast(the_path[6] - 0x30);
+ std.debug.print("user_id: {d}\n", .{user_id});
+ std.debug.print("users: {d}\n", .{users.count()});
const user = users.get(user_id);
+ std.debug.print("user: {?}\n", .{user});
- var buf: [100]u8 = undefined;
+ var buf: [256]u8 = undefined;
var json_to_send: []const u8 = undefined;
- if (zap.util.stringifyBuf(&buf, user, .{})) |json| {
- json_to_send = json;
- } else {
- json_to_send = "null";
- }
+ json_to_send = try zap.util.stringifyBuf(&buf, user, .{});
+
std.debug.print("<< json: {s}\n", .{json_to_send});
r.setContentType(.JSON) catch return;
r.setContentTypeFromFilename("test.json") catch return;
diff --git a/examples/http_params/http_params.zig b/examples/http_params/http_params.zig
index e387e9b..66976f6 100644
--- a/examples/http_params/http_params.zig
+++ b/examples/http_params/http_params.zig
@@ -32,7 +32,7 @@ pub fn main() !void {
const Handler = struct {
var alloc: std.mem.Allocator = undefined;
- pub fn on_request(r: zap.Request) void {
+ pub fn on_request(r: zap.Request) !void {
std.debug.print("\n=====================================================\n", .{});
defer std.debug.print("=====================================================\n\n", .{});
@@ -69,7 +69,7 @@ pub fn main() !void {
// ================================================================
// iterate over all params as strings
- var strparams = r.parametersToOwnedStrList(alloc, false) catch unreachable;
+ var strparams = try r.parametersToOwnedStrList(alloc, false);
defer strparams.deinit();
std.debug.print("\n", .{});
for (strparams.items) |kv| {
@@ -79,7 +79,7 @@ pub fn main() !void {
std.debug.print("\n", .{});
// iterate over all params
- const params = r.parametersToOwnedList(alloc, false) catch unreachable;
+ const params = try r.parametersToOwnedList(alloc, false);
defer params.deinit();
for (params.items) |kv| {
std.log.info("Param `{s}` is {any}", .{ kv.key.str, kv.value });
diff --git a/examples/https/https.zig b/examples/https/https.zig
index 2806179..bf9331b 100644
--- a/examples/https/https.zig
+++ b/examples/https/https.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request_verbose(r: zap.Request) void {
+fn on_request_verbose(r: zap.Request) !void {
if (r.path) |the_path| {
std.debug.print("PATH: {s}\n", .{the_path});
}
@@ -9,11 +9,11 @@ fn on_request_verbose(r: zap.Request) void {
if (r.query) |the_query| {
std.debug.print("QUERY: {s}\n", .{the_query});
}
- r.sendBody("Hello from ZAP!!!
") catch return;
+ try r.sendBody("Hello from ZAP!!!
");
}
-fn on_request_minimal(r: zap.Request) void {
- r.sendBody("Hello from ZAP!!!
") catch return;
+fn on_request_minimal(r: zap.Request) !void {
+ try r.sendBody("Hello from ZAP!!!
");
}
fn help_and_exit(filename: []const u8, err: anyerror) void {
diff --git a/examples/middleware/middleware.zig b/examples/middleware/middleware.zig
index 776a930..a02895f 100644
--- a/examples/middleware/middleware.zig
+++ b/examples/middleware/middleware.zig
@@ -69,7 +69,7 @@ const UserMiddleWare = struct {
}
// note that the first parameter is of type *Handler, not *Self !!!
- pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) bool {
+ pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) !bool {
// this is how we would get our self pointer
const self: *Self = @fieldParentPtr("handler", handler);
@@ -113,7 +113,7 @@ const SessionMiddleWare = struct {
}
// note that the first parameter is of type *Handler, not *Self !!!
- pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) bool {
+ pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) !bool {
// this is how we would get our self pointer
const self: *Self = @fieldParentPtr("handler", handler);
_ = self;
@@ -148,7 +148,7 @@ const HtmlMiddleWare = struct {
}
// note that the first parameter is of type *Handler, not *Self !!!
- pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) bool {
+ pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) !bool {
// this is how we would get our self pointer
const self: *Self = @fieldParentPtr("handler", handler);
diff --git a/examples/middleware_with_endpoint/middleware_with_endpoint.zig b/examples/middleware_with_endpoint/middleware_with_endpoint.zig
index 3bf9551..4d5f8b4 100644
--- a/examples/middleware_with_endpoint/middleware_with_endpoint.zig
+++ b/examples/middleware_with_endpoint/middleware_with_endpoint.zig
@@ -57,7 +57,7 @@ const UserMiddleWare = struct {
}
// note that the first parameter is of type *Handler, not *Self !!!
- pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) bool {
+ pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) !bool {
// this is how we would get our self pointer
const self: *Self = @fieldParentPtr("handler", handler);
@@ -103,7 +103,7 @@ const SessionMiddleWare = struct {
}
// note that the first parameter is of type *Handler, not *Self !!!
- pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) bool {
+ pub fn onRequest(handler: *Handler, r: zap.Request, context: *Context) !bool {
// this is how we would get our self pointer
const self: *Self = @fieldParentPtr("handler", handler);
_ = self;
@@ -146,13 +146,13 @@ const HtmlEndpoint = struct {
};
}
- pub fn post(_: *HtmlEndpoint, _: zap.Request) void {}
- pub fn put(_: *HtmlEndpoint, _: zap.Request) void {}
- pub fn delete(_: *HtmlEndpoint, _: zap.Request) void {}
- pub fn patch(_: *HtmlEndpoint, _: zap.Request) void {}
- pub fn options(_: *HtmlEndpoint, _: zap.Request) void {}
+ pub fn post(_: *HtmlEndpoint, _: zap.Request) !void {}
+ pub fn put(_: *HtmlEndpoint, _: zap.Request) !void {}
+ pub fn delete(_: *HtmlEndpoint, _: zap.Request) !void {}
+ pub fn patch(_: *HtmlEndpoint, _: zap.Request) !void {}
+ pub fn options(_: *HtmlEndpoint, _: zap.Request) !void {}
- pub fn get(_: *Self, r: zap.Request) void {
+ pub fn get(_: *Self, r: zap.Request) !void {
var buf: [1024]u8 = undefined;
var userFound: bool = false;
var sessionFound: bool = false;
@@ -169,12 +169,12 @@ const HtmlEndpoint = struct {
sessionFound = true;
std.debug.assert(r.isFinished() == false);
- const message = std.fmt.bufPrint(&buf, "User: {s} / {s}, Session: {s} / {s}", .{
+ const message = try std.fmt.bufPrint(&buf, "User: {s} / {s}, Session: {s} / {s}", .{
user.name,
user.email,
session.info,
session.token,
- }) catch unreachable;
+ });
r.setContentType(.TEXT) catch unreachable;
r.sendBody(message) catch unreachable;
std.debug.assert(r.isFinished() == true);
diff --git a/examples/mustache/mustache.zig b/examples/mustache/mustache.zig
index 26dd6d9..37ea7db 100644
--- a/examples/mustache/mustache.zig
+++ b/examples/mustache/mustache.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const zap = @import("zap");
const Mustache = @import("zap").Mustache;
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
const template =
\\ {{=<< >>=}}
\\ * Users:
diff --git a/examples/routes/routes.zig b/examples/routes/routes.zig
index 43222d1..d605f3e 100644
--- a/examples/routes/routes.zig
+++ b/examples/routes/routes.zig
@@ -3,39 +3,39 @@ const zap = @import("zap");
// NOTE: this is a super simplified example, just using a hashmap to map
// from HTTP path to request function.
-fn dispatch_routes(r: zap.Request) void {
+fn dispatch_routes(r: zap.Request) !void {
// dispatch
if (r.path) |the_path| {
if (routes.get(the_path)) |foo| {
- foo(r);
+ try foo(r);
return;
}
}
// or default: present menu
- r.sendBody(
+ try r.sendBody(
\\
\\
\\ static
\\ dynamic
\\
\\
- ) catch return;
+ );
}
-fn static_site(r: zap.Request) void {
- r.sendBody("Hello from STATIC ZAP!
") catch return;
+fn static_site(r: zap.Request) !void {
+ try r.sendBody("Hello from STATIC ZAP!
");
}
var dynamic_counter: i32 = 0;
-fn dynamic_site(r: zap.Request) void {
+fn dynamic_site(r: zap.Request) !void {
dynamic_counter += 1;
var buf: [128]u8 = undefined;
- const filled_buf = std.fmt.bufPrintZ(
+ const filled_buf = try std.fmt.bufPrintZ(
&buf,
"Hello # {d} from DYNAMIC ZAP!!!
",
.{dynamic_counter},
- ) catch "ERROR";
- r.sendBody(filled_buf) catch return;
+ );
+ try r.sendBody(filled_buf);
}
fn setup_routes(a: std.mem.Allocator) !void {
diff --git a/examples/senderror/senderror.zig b/examples/senderror/senderror.zig
index a9756ce..3fb0c81 100644
--- a/examples/senderror/senderror.zig
+++ b/examples/senderror/senderror.zig
@@ -5,7 +5,7 @@ fn MAKE_MEGA_ERROR() !void {
return error.MEGA_ERROR;
}
-fn MY_REQUEST_HANDLER(r: zap.Request) void {
+fn MY_REQUEST_HANDLER(r: zap.Request) !void {
MAKE_MEGA_ERROR() catch |err| {
r.sendError(err, if (@errorReturnTrace()) |t| t.* else null, 505);
};
diff --git a/examples/sendfile/sendfile.zig b/examples/sendfile/sendfile.zig
index 4c97309..a4ac59e 100644
--- a/examples/sendfile/sendfile.zig
+++ b/examples/sendfile/sendfile.zig
@@ -6,7 +6,7 @@ var read_len: ?usize = null;
const testfile = @embedFile("testfile.txt");
-pub fn on_request(r: zap.Request) void {
+pub fn on_request(r: zap.Request) !void {
// Sends a file if present in the filesystem orelse returns an error.
//
// - efficiently sends a file using gzip compression
diff --git a/examples/serve/serve.zig b/examples/serve/serve.zig
index d9f9d65..789257e 100644
--- a/examples/serve/serve.zig
+++ b/examples/serve/serve.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
r.setStatus(.not_found);
r.sendBody("404 - File not found
") catch return;
}
diff --git a/examples/simple_router/simple_router.zig b/examples/simple_router/simple_router.zig
index eb58839..cacbcc3 100644
--- a/examples/simple_router/simple_router.zig
+++ b/examples/simple_router/simple_router.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const zap = @import("zap");
const Allocator = std.mem.Allocator;
-fn on_request_verbose(r: zap.Request) void {
+fn on_request_verbose(r: zap.Request) !void {
if (r.path) |the_path| {
std.debug.print("PATH: {s}\n", .{the_path});
}
@@ -28,7 +28,7 @@ pub const SomePackage = struct {
};
}
- pub fn getA(self: *Self, req: zap.Request) void {
+ pub fn getA(self: *Self, req: zap.Request) !void {
std.log.warn("get_a_requested", .{});
const string = std.fmt.allocPrint(
@@ -41,7 +41,7 @@ pub const SomePackage = struct {
req.sendBody(string) catch return;
}
- pub fn getB(self: *Self, req: zap.Request) void {
+ pub fn getB(self: *Self, req: zap.Request) !void {
std.log.warn("get_b_requested", .{});
const string = std.fmt.allocPrint(
@@ -54,7 +54,7 @@ pub const SomePackage = struct {
req.sendBody(string) catch return;
}
- pub fn incrementA(self: *Self, req: zap.Request) void {
+ pub fn incrementA(self: *Self, req: zap.Request) !void {
std.log.warn("increment_a_requested", .{});
self.a += 1;
@@ -63,10 +63,10 @@ pub const SomePackage = struct {
}
};
-fn not_found(req: zap.Request) void {
+fn not_found(req: zap.Request) !void {
std.debug.print("not found handler", .{});
- req.sendBody("Not found") catch return;
+ try req.sendBody("Not found");
}
pub fn main() !void {
diff --git a/examples/userpass_session_auth/userpass_session_auth.zig b/examples/userpass_session_auth/userpass_session_auth.zig
index 550bfbb..c421ddc 100644
--- a/examples/userpass_session_auth/userpass_session_auth.zig
+++ b/examples/userpass_session_auth/userpass_session_auth.zig
@@ -25,38 +25,38 @@ const img = @embedFile("./html/Ziggy_the_Ziguana.svg.png");
var authenticator: Authenticator = undefined;
// the login page (embedded)
-fn on_login(r: zap.Request) void {
- r.sendBody(loginpage) catch return;
+fn on_login(r: zap.Request) !void {
+ try r.sendBody(loginpage);
}
// the "normal page"
-fn on_normal_page(r: zap.Request) void {
+fn on_normal_page(r: zap.Request) !void {
zap.debug("on_normal_page()\n", .{});
- r.sendBody(
+ try r.sendBody(
\\
\\ Hello from ZAP!!!
\\ You are logged in!!!>
\\
logout
\\
- ) catch return;
+ );
}
// the logged-out page
-fn on_logout(r: zap.Request) void {
+fn on_logout(r: zap.Request) !void {
zap.debug("on_logout()\n", .{});
authenticator.logout(&r);
// note, the link below doesn't matter as the authenticator will send us
// straight to the /login page
- r.sendBody(
+ try r.sendBody(
\\
\\ You are logged out!!!
\\
\\ Log back in
\\
- ) catch return;
+ );
}
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
switch (authenticator.authenticateRequest(&r)) {
.Handled => {
// the authenticator handled the entire request for us.
@@ -80,8 +80,8 @@ fn on_request(r: zap.Request) void {
// the authenticator. Hence, we name the img for the /login
// page: /login/Ziggy....png
if (std.mem.startsWith(u8, p, "/login/Ziggy_the_Ziguana.svg.png")) {
- r.setContentTypeFromPath() catch unreachable;
- r.sendBody(img) catch unreachable;
+ try r.setContentTypeFromPath();
+ try r.sendBody(img);
return;
}
diff --git a/examples/websockets/websockets.zig b/examples/websockets/websockets.zig
index e347242..d0e3cee 100644
--- a/examples/websockets/websockets.zig
+++ b/examples/websockets/websockets.zig
@@ -163,13 +163,13 @@ fn handle_websocket_message(
//
// HTTP stuff
//
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
r.setHeader("Server", "zap.example") catch unreachable;
- r.sendBody(
+ try r.sendBody(
\\
\\ This is a simple Websocket chatroom example
\\
- ) catch return;
+ );
}
fn on_upgrade(r: zap.Request, target_protocol: []const u8) void {
diff --git a/src/endpoint.zig b/src/endpoint.zig
index d9b1b6e..6b7dd95 100644
--- a/src/endpoint.zig
+++ b/src/endpoint.zig
@@ -55,6 +55,16 @@ const std = @import("std");
const zap = @import("zap.zig");
const auth = @import("http_auth.zig");
+/// Endpoint request error handling strategy
+pub const ErrorStrategy = enum {
+ /// log errors to console
+ log_to_console,
+ /// log errors to console AND generate a HTML response
+ log_to_response,
+ /// raise errors -> TODO: clarify: where can they be caught? in App.run()
+ raise,
+};
+
// zap types
const Request = zap.Request;
const ListenerSettings = zap.HttpListenerSettings;
@@ -69,6 +79,14 @@ pub fn checkEndpointType(T: type) void {
@compileError(@typeName(T) ++ " has no path field");
}
+ if (@hasField(T, "error_strategy")) {
+ if (@FieldType(T, "error_strategy") != ErrorStrategy) {
+ @compileError(@typeName(@FieldType(T, "error_strategy")) ++ " has wrong type, expected: zap.Endpoint.ErrorStrategy");
+ }
+ } else {
+ @compileError(@typeName(T) ++ " has no error_strategy field");
+ }
+
const methods_to_check = [_][]const u8{
"get",
"post",
@@ -79,8 +97,8 @@ pub fn checkEndpointType(T: type) void {
};
inline for (methods_to_check) |method| {
if (@hasDecl(T, method)) {
- if (@TypeOf(@field(T, method)) != fn (_: *T, _: Request) void) {
- @compileError(method ++ " method of " ++ @typeName(T) ++ " has wrong type:\n" ++ @typeName(@TypeOf(T.get)) ++ "\nexpected:\n" ++ @typeName(fn (_: *T, _: Request) void));
+ if (@TypeOf(@field(T, method)) != fn (_: *T, _: Request) anyerror!void) {
+ @compileError(method ++ " method of " ++ @typeName(T) ++ " has wrong type:\n" ++ @typeName(@TypeOf(T.get)) ++ "\nexpected:\n" ++ @typeName(fn (_: *T, _: Request) anyerror!void));
}
} else {
@compileError(@typeName(T) ++ " has no method named `" ++ method ++ "`");
@@ -88,58 +106,65 @@ pub fn checkEndpointType(T: type) void {
}
}
-const EndpointWrapper = struct {
- pub const Wrapper = struct {
- call: *const fn (*Wrapper, zap.Request) void = undefined,
+pub const Wrapper = struct {
+ pub const Internal = struct {
+ call: *const fn (*Internal, zap.Request) anyerror!void = undefined,
path: []const u8,
- destroy: *const fn (allocator: std.mem.Allocator, *Wrapper) void = undefined,
+ destroy: *const fn (allocator: std.mem.Allocator, *Internal) void = undefined,
};
pub fn Wrap(T: type) type {
return struct {
wrapped: *T,
- wrapper: Wrapper,
+ wrapper: Internal,
const Self = @This();
- pub fn unwrap(wrapper: *Wrapper) *Self {
+ pub fn unwrap(wrapper: *Internal) *Self {
const self: *Self = @alignCast(@fieldParentPtr("wrapper", wrapper));
return self;
}
- pub fn destroy(allocator: std.mem.Allocator, wrapper: *Wrapper) void {
+ pub fn destroy(allocator: std.mem.Allocator, wrapper: *Internal) void {
const self: *Self = @alignCast(@fieldParentPtr("wrapper", wrapper));
allocator.destroy(self);
}
- pub fn onRequestWrapped(wrapper: *Wrapper, r: zap.Request) void {
+ pub fn onRequestWrapped(wrapper: *Internal, r: zap.Request) !void {
var self: *Self = Self.unwrap(wrapper);
- self.onRequest(r);
+ try self.onRequest(r);
}
- pub fn onRequest(self: *Self, r: zap.Request) void {
- switch (r.methodAsEnum()) {
- .GET => return self.wrapped.*.get(r),
- .POST => return self.wrapped.*.post(r),
- .PUT => return self.wrapped.*.put(r),
- .DELETE => return self.wrapped.*.delete(r),
- .PATCH => return self.wrapped.*.patch(r),
- .OPTIONS => return self.wrapped.*.options(r),
- else => {
- // TODO: log that method is ignored
- },
+ pub fn onRequest(self: *Self, r: zap.Request) !void {
+ const ret = switch (r.methodAsEnum()) {
+ .GET => self.wrapped.*.get(r),
+ .POST => self.wrapped.*.post(r),
+ .PUT => self.wrapped.*.put(r),
+ .DELETE => self.wrapped.*.delete(r),
+ .PATCH => self.wrapped.*.patch(r),
+ .OPTIONS => self.wrapped.*.options(r),
+ else => error.UnsupportedHtmlRequestMethod,
+ };
+ if (ret) {
+ // handled without error
+ } else |err| {
+ switch (self.wrapped.*.error_strategy) {
+ .raise => return err,
+ .log_to_response => return r.sendError(err, if (@errorReturnTrace()) |t| t.* else null, 505),
+ .log_to_console => zap.debug("Error in {} {s} : {}", .{ Self, r.method orelse "(no method)", err }),
+ }
}
}
};
}
- pub fn init(T: type, value: *T) EndpointWrapper.Wrap(T) {
+ pub fn init(T: type, value: *T) Wrapper.Wrap(T) {
checkEndpointType(T);
- var ret: EndpointWrapper.Wrap(T) = .{
+ var ret: Wrapper.Wrap(T) = .{
.wrapped = value,
.wrapper = .{ .path = value.path },
};
- ret.wrapper.call = EndpointWrapper.Wrap(T).onRequestWrapped;
- ret.wrapper.destroy = EndpointWrapper.Wrap(T).destroy;
+ ret.wrapper.call = Wrapper.Wrap(T).onRequestWrapped;
+ ret.wrapper.destroy = Wrapper.Wrap(T).destroy;
return ret;
}
};
@@ -150,6 +175,7 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
authenticator: *Authenticator,
ep: *EndpointType,
path: []const u8,
+ error_strategy: ErrorStrategy,
const Self = @This();
/// Init the authenticating endpoint. Pass in a pointer to the endpoint
@@ -160,61 +186,62 @@ pub fn Authenticating(EndpointType: type, Authenticator: type) type {
.authenticator = authenticator,
.ep = e,
.path = e.path,
+ .error_strategy = e.error_strategy,
};
}
/// Authenticates GET requests using the Authenticator.
- pub fn get(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn get(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.get(r),
.Handled => {},
- }
+ };
}
/// Authenticates POST requests using the Authenticator.
- pub fn post(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn post(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.post(r),
.Handled => {},
- }
+ };
}
/// Authenticates PUT requests using the Authenticator.
- pub fn put(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn put(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.put(r),
.Handled => {},
- }
+ };
}
/// Authenticates DELETE requests using the Authenticator.
- pub fn delete(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn delete(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.delete(r),
.Handled => {},
- }
+ };
}
/// Authenticates PATCH requests using the Authenticator.
- pub fn patch(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn patch(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.patch(r),
.Handled => {},
- }
+ };
}
/// Authenticates OPTIONS requests using the Authenticator.
- pub fn options(self: *Self, r: zap.Request) void {
- switch (self.authenticator.authenticateRequest(&r)) {
+ pub fn options(self: *Self, r: zap.Request) anyerror!void {
+ try switch (self.authenticator.authenticateRequest(&r)) {
.AuthFailed => return self.ep.*.unauthorized(r),
.AuthOK => self.ep.*.put(r),
.Handled => {},
- }
+ };
}
};
}
@@ -237,7 +264,7 @@ pub const Listener = struct {
const Self = @This();
/// Internal static struct of member endpoints
- var endpoints: std.ArrayListUnmanaged(*EndpointWrapper.Wrapper) = .empty;
+ var endpoints: std.ArrayListUnmanaged(*Wrapper.Internal) = .empty;
/// Internal, static request handler callback. Will be set to the optional,
/// user-defined request callback that only gets called if no endpoints match
@@ -303,23 +330,22 @@ pub const Listener = struct {
}
const EndpointType = @typeInfo(@TypeOf(e)).pointer.child;
checkEndpointType(EndpointType);
- const wrapper = try self.allocator.create(EndpointWrapper.Wrap(EndpointType));
- wrapper.* = EndpointWrapper.init(EndpointType, e);
+ const wrapper = try self.allocator.create(Wrapper.Wrap(EndpointType));
+ wrapper.* = Wrapper.init(EndpointType, e);
try endpoints.append(self.allocator, &wrapper.wrapper);
}
- fn onRequest(r: Request) void {
+ fn onRequest(r: Request) !void {
if (r.path) |p| {
for (endpoints.items) |wrapper| {
if (std.mem.startsWith(u8, p, wrapper.path)) {
- wrapper.call(wrapper, r);
- return;
+ return try wrapper.call(wrapper, r);
}
}
}
// if set, call the user-provided default callback
if (on_request) |foo| {
- foo(r);
+ try foo(r);
}
}
};
diff --git a/src/middleware.zig b/src/middleware.zig
index 0373280..b5b92e2 100644
--- a/src/middleware.zig
+++ b/src/middleware.zig
@@ -17,7 +17,7 @@ pub fn Handler(comptime ContextType: anytype) type {
// will be set
allocator: ?std.mem.Allocator = null,
- pub const RequestFn = *const fn (*Self, zap.Request, *ContextType) bool;
+ pub const RequestFn = *const fn (*Self, zap.Request, *ContextType) anyerror!bool;
const Self = @This();
pub fn init(on_request: RequestFn, other: ?*Self) Self {
@@ -30,7 +30,7 @@ pub fn Handler(comptime ContextType: anytype) type {
// example for handling a request request
// which you can use in your components, e.g.:
// return self.handler.handleOther(r, context);
- pub fn handleOther(self: *Self, r: zap.Request, context: *ContextType) bool {
+ pub fn handleOther(self: *Self, r: zap.Request, context: *ContextType) !bool {
// in structs embedding a handler, we'd @fieldParentPtr the first
// param to get to the real self
@@ -41,7 +41,7 @@ pub fn Handler(comptime ContextType: anytype) type {
var other_handler_finished = false;
if (self.other_handler) |other_handler| {
if (other_handler.on_request) |on_request| {
- other_handler_finished = on_request(other_handler, r, context);
+ other_handler_finished = try on_request(other_handler, r, context);
}
}
@@ -96,19 +96,19 @@ pub fn EndpointHandler(comptime HandlerType: anytype, comptime EndpointType: any
///
/// If `breakOnFinish` is `true`, the handler will stop handing requests down the chain if
/// the endpoint processed the request.
- pub fn onRequest(handler: *HandlerType, r: zap.Request, context: *ContextType) bool {
+ pub fn onRequest(handler: *HandlerType, r: zap.Request, context: *ContextType) !bool {
const self: *Self = @fieldParentPtr("handler", handler);
r.setUserContext(context);
if (!self.options.checkPath or
std.mem.startsWith(u8, r.path orelse "", self.endpoint.path))
{
switch (r.methodAsEnum()) {
- .GET => self.endpoint.*.get(r),
- .POST => self.endpoint.*.post(r),
- .PUT => self.endpoint.*.put(r),
- .DELETE => self.endpoint.*.delete(r),
- .PATCH => self.endpoint.*.patch(r),
- .OPTIONS => self.endpoint.*.options(r),
+ .GET => try self.endpoint.*.get(r),
+ .POST => try self.endpoint.*.post(r),
+ .PUT => try self.endpoint.*.put(r),
+ .DELETE => try self.endpoint.*.delete(r),
+ .PATCH => try self.endpoint.*.patch(r),
+ .OPTIONS => try self.endpoint.*.options(r),
else => {},
}
}
@@ -176,7 +176,7 @@ pub fn Listener(comptime ContextType: anytype) type {
/// Create your own listener if you want different behavior.
/// (Didn't want to make this a callback. Submit an issue if you really
/// think that's an issue).
- pub fn onRequest(r: zap.Request) void {
+ pub fn onRequest(r: zap.Request) !void {
// we are the 1st handler in the chain, so we create a context
var context: ContextType = .{};
@@ -191,7 +191,7 @@ pub fn Listener(comptime ContextType: anytype) type {
initial_handler.allocator = allocator;
if (initial_handler.on_request) |on_request| {
// we don't care about the return value at the top level
- _ = on_request(initial_handler, r, &context);
+ _ = try on_request(initial_handler, r, &context);
}
}
}
diff --git a/src/router.zig b/src/router.zig
index c9ca7d5..53500a6 100644
--- a/src/router.zig
+++ b/src/router.zig
@@ -21,7 +21,7 @@ pub const Options = struct {
};
const CallbackTag = enum { bound, unbound };
-const BoundHandler = *fn (*const anyopaque, zap.Request) void;
+const BoundHandler = *fn (*const anyopaque, zap.Request) anyerror!void;
const Callback = union(CallbackTag) {
bound: struct { instance: usize, handler: usize },
unbound: zap.HttpRequestFn,
@@ -94,24 +94,24 @@ pub fn on_request_handler(self: *Self) zap.HttpRequestFn {
return zap_on_request;
}
-fn zap_on_request(r: zap.Request) void {
+fn zap_on_request(r: zap.Request) !void {
return serve(_instance, r);
}
-fn serve(self: *Self, r: zap.Request) void {
+fn serve(self: *Self, r: zap.Request) !void {
const path = r.path orelse "/";
if (self.routes.get(path)) |routeInfo| {
switch (routeInfo) {
- .bound => |b| @call(.auto, @as(BoundHandler, @ptrFromInt(b.handler)), .{ @as(*anyopaque, @ptrFromInt(b.instance)), r }),
- .unbound => |h| h(r),
+ .bound => |b| try @call(.auto, @as(BoundHandler, @ptrFromInt(b.handler)), .{ @as(*anyopaque, @ptrFromInt(b.instance)), r }),
+ .unbound => |h| try h(r),
}
} else if (self.not_found) |handler| {
// not found handler
- handler(r);
+ try handler(r);
} else {
// default 404 output
r.setStatus(.not_found);
- r.sendBody("404 Not Found") catch return;
+ try r.sendBody("404 Not Found");
}
}
diff --git a/src/tests/test_auth.zig b/src/tests/test_auth.zig
index b33487d..1dba9a1 100644
--- a/src/tests/test_auth.zig
+++ b/src/tests/test_auth.zig
@@ -149,8 +149,9 @@ fn makeRequestThread(a: std.mem.Allocator, url: []const u8, auth: ?ClientAuthReq
pub const Endpoint = struct {
path: []const u8,
+ error_strategy: zap.Endpoint.ErrorStrategy = .raise,
- pub fn get(e: *Endpoint, r: zap.Request) void {
+ pub fn get(e: *Endpoint, r: zap.Request) !void {
_ = e;
r.sendBody(HTTP_RESPONSE) catch return;
received_response = HTTP_RESPONSE;
@@ -158,7 +159,7 @@ pub const Endpoint = struct {
zap.stop();
}
- pub fn unauthorized(e: *Endpoint, r: zap.Request) void {
+ pub fn unauthorized(e: *Endpoint, r: zap.Request) !void {
_ = e;
r.setStatus(.unauthorized);
r.sendBody("UNAUTHORIZED ACCESS") catch return;
@@ -166,11 +167,11 @@ pub const Endpoint = struct {
std.time.sleep(1 * std.time.ns_per_s);
zap.stop();
}
- pub fn post(_: *Endpoint, _: zap.Request) void {}
- pub fn put(_: *Endpoint, _: zap.Request) void {}
- pub fn delete(_: *Endpoint, _: zap.Request) void {}
- pub fn patch(_: *Endpoint, _: zap.Request) void {}
- pub fn options(_: *Endpoint, _: zap.Request) void {}
+ pub fn post(_: *Endpoint, _: zap.Request) !void {}
+ pub fn put(_: *Endpoint, _: zap.Request) !void {}
+ pub fn delete(_: *Endpoint, _: zap.Request) !void {}
+ pub fn patch(_: *Endpoint, _: zap.Request) !void {}
+ pub fn options(_: *Endpoint, _: zap.Request) !void {}
};
//
// end of http client code
diff --git a/src/tests/test_http_params.zig b/src/tests/test_http_params.zig
index 31f8b0d..167cbc0 100644
--- a/src/tests/test_http_params.zig
+++ b/src/tests/test_http_params.zig
@@ -30,7 +30,7 @@ test "http parameters" {
var paramOneSlice: ?[]const u8 = null;
var paramSlices: zap.Request.ParamSliceIterator = undefined;
- pub fn on_request(r: zap.Request) void {
+ pub fn on_request(r: zap.Request) !void {
ran = true;
r.parseQuery();
param_count = r.getParamCount();
diff --git a/src/tests/test_sendfile.zig b/src/tests/test_sendfile.zig
index 8b16a8a..964ee99 100644
--- a/src/tests/test_sendfile.zig
+++ b/src/tests/test_sendfile.zig
@@ -24,7 +24,7 @@ fn makeRequest(a: std.mem.Allocator, url: []const u8) !void {
fn makeRequestThread(a: std.mem.Allocator, url: []const u8) !std.Thread {
return try std.Thread.spawn(.{}, makeRequest, .{ a, url });
}
-pub fn on_request(r: zap.Request) void {
+pub fn on_request(r: zap.Request) !void {
r.sendFile("src/tests/testfile.txt") catch unreachable;
}
diff --git a/src/util.zig b/src/util.zig
index 4b6a4c9..663155c 100644
--- a/src/util.zig
+++ b/src/util.zig
@@ -74,12 +74,12 @@ pub fn stringifyBuf(
buffer: []u8,
value: anytype,
options: std.json.StringifyOptions,
-) ?[]const u8 {
+) ![]const u8 {
var fba = std.heap.FixedBufferAllocator.init(buffer);
var string = std.ArrayList(u8).init(fba.allocator());
if (std.json.stringify(value, options, string.writer())) {
return string.items;
- } else |_| { // error
- return null;
+ } else |err| { // error
+ return err;
}
}
diff --git a/src/zap.zig b/src/zap.zig
index bce9853..93d3ecb 100644
--- a/src/zap.zig
+++ b/src/zap.zig
@@ -132,7 +132,7 @@ pub const ContentType = enum {
pub const FioHttpRequestFn = *const fn (r: [*c]fio.http_s) callconv(.C) void;
/// Zap Http request callback function type.
-pub const HttpRequestFn = *const fn (Request) void;
+pub const HttpRequestFn = *const fn (Request) anyerror!void;
/// websocket connection upgrade callback type
/// fn(request, targetstring)
@@ -202,8 +202,10 @@ pub const HttpListener = struct {
req.markAsFinished(false);
std.debug.assert(l.settings.on_request != null);
if (l.settings.on_request) |on_request| {
- // l.settings.on_request.?(req);
- on_request(req);
+ on_request(req) catch |err| {
+ // TODO: log / handle the error in a better way
+ std.debug.print("zap on_request error: {}", .{err});
+ };
}
}
}
@@ -225,7 +227,10 @@ pub const HttpListener = struct {
var user_context: Request.UserContext = .{};
req._user_context = &user_context;
- l.settings.on_response.?(req);
+ l.settings.on_response.?(req) catch |err| {
+ // TODO: log / handle the error in a better way
+ std.debug.print("zap on_response error: {}", .{err});
+ };
}
}
diff --git a/tools/docserver.zig b/tools/docserver.zig
index e6fc5ba..5368f20 100644
--- a/tools/docserver.zig
+++ b/tools/docserver.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request(r: zap.Request) void {
+fn on_request(r: zap.Request) !void {
r.setStatus(.not_found);
r.sendBody("404 - File not found
") catch return;
}
diff --git a/wrk/zig/main.zig b/wrk/zig/main.zig
index 20fa3f3..ef68612 100644
--- a/wrk/zig/main.zig
+++ b/wrk/zig/main.zig
@@ -1,8 +1,8 @@
const std = @import("std");
const zap = @import("zap");
-fn on_request_minimal(r: zap.Request) void {
- r.sendBody("Hello from ZAP!!!") catch return;
+fn on_request_minimal(r: zap.Request) !void {
+ try r.sendBody("Hello from ZAP!!!");
}
pub fn main() !void {