diff --git a/src/http/Server.zig b/src/http/Server.zig index 13f1bb0..d26e3d4 100644 --- a/src/http/Server.zig +++ b/src/http/Server.zig @@ -5,6 +5,8 @@ const RateLimiter = @import("RateLimiter.zig"); const Server = @This(); +const log = std.log.scoped(.server); + allocator: std.mem.Allocator, httpz_server: httpz.Server(*Context), context: Context, @@ -12,6 +14,25 @@ context: Context, const Context = struct { options: handler.HandleWeatherOptions, rate_limiter: *RateLimiter, + + fn uncaughtError(req: *httpz.Request, res: *httpz.Response, err: anyerror) void { + res.status = 500; + res.body = "Internal Server Error"; + log.warn("unhandled exception for request: {s}", .{req.url.raw}); + var buf: [4096]u8 = undefined; + var fixed_writer: std.Io.Writer = .fixed(&buf); + var it = req.headers.iterator(); + while (it.next()) |header| + fixed_writer.print("\t{s}: {s}\n", .{ header.key, header.value }) catch { + log.warn("headers: NOT AVAILABLE", .{}); + log.warn("error: {}", .{err}); + + return; + }; + + log.warn("headers: \n{s}", .{fixed_writer.buffered()}); + log.warn("error: {}", .{err}); + } }; pub fn init( @@ -62,7 +83,7 @@ fn rateLimitMiddleware(limiter: *RateLimiter, req: *httpz.Request, res: *httpz.R } pub fn listen(self: *Server) !void { - std.log.info("wttr listening on port {d}", .{self.httpz_server.config.port.?}); + log.info("wttr listening on port {d}", .{self.httpz_server.config.port.?}); try self.httpz_server.listen(); } diff --git a/src/http/handler.zig b/src/http/handler.zig index 6540078..95e4fb3 100644 --- a/src/http/handler.zig +++ b/src/http/handler.zig @@ -36,6 +36,7 @@ pub fn handleWeather( } else { // Fall back to IP-based detection const client_ip = getClientIP(req); + std.log.debug("No location requested, using IP address '{s}'", .{client_ip}); break :blk client_ip; } }; diff --git a/src/location/GeoCache.zig b/src/location/GeoCache.zig index 7d62b81..958f9ec 100644 --- a/src/location/GeoCache.zig +++ b/src/location/GeoCache.zig @@ -3,6 +3,8 @@ const Coordinates = @import("../Coordinates.zig"); const GeoCache = @This(); +const log = std.log.scoped(.geocache); + allocator: std.mem.Allocator, cache: std.StringHashMap(CachedLocation), cache_file: ?[]const u8, @@ -20,7 +22,7 @@ pub fn init(allocator: std.mem.Allocator, cache_file: ?[]const u8) !GeoCache { // Load from file if specified if (cache_file) |file_path| { loadFromFile(allocator, &cache, file_path) catch |err| { - std.log.warn("Failed to load geocoding cache from {s}: {}", .{ file_path, err }); + log.warn("Failed to load geocoding cache from {s}: {}", .{ file_path, err }); }; } @@ -37,7 +39,7 @@ pub fn deinit(self: *GeoCache) void { // Save to file if specified if (self.cache_file) |file_path| { self.saveToFile(file_path) catch |err| { - std.log.warn("Failed to save geocoding cache to {s}: {}", .{ file_path, err }); + log.warn("Failed to save geocoding cache to {s}: {}", .{ file_path, err }); }; } @@ -78,7 +80,7 @@ pub fn saveIfNeeded(self: *GeoCache) void { if (elapsed_ms < fifteen_minutes_ms) return; self.saveToFile(cache_file) catch |err| { - std.log.warn("Failed to save geocoding cache to {s}: {}", .{ cache_file, err }); + log.warn("Failed to save geocoding cache to {s}: {}", .{ cache_file, err }); return; }; diff --git a/src/location/resolver.zig b/src/location/resolver.zig index a55c058..02dcf53 100644 --- a/src/location/resolver.zig +++ b/src/location/resolver.zig @@ -86,6 +86,8 @@ pub const Resolver = struct { } fn resolveGeocoded(self: *Resolver, name: []const u8) !Location { + // Don't bother passing this through + if (std.mem.eql(u8, name, "favicon.ico")) return error.GeocodingFailed; // Check cache first if (self.geocache.get(name)) |cached| { return Location{