error pages

This commit is contained in:
Sky Johnson 2025-03-25 12:13:26 -05:00
parent 0259d1a135
commit 474ed89dda
3 changed files with 49 additions and 8 deletions

View File

@ -10,6 +10,7 @@ import (
"git.sharkk.net/Sky/Moonshark/core/logger" "git.sharkk.net/Sky/Moonshark/core/logger"
"git.sharkk.net/Sky/Moonshark/core/routers" "git.sharkk.net/Sky/Moonshark/core/routers"
"git.sharkk.net/Sky/Moonshark/core/runner" "git.sharkk.net/Sky/Moonshark/core/runner"
"git.sharkk.net/Sky/Moonshark/core/utils"
) )
// Server handles HTTP requests using Lua and static file routers // Server handles HTTP requests using Lua and static file routers
@ -20,10 +21,15 @@ type Server struct {
logger *logger.Logger logger *logger.Logger
httpServer *http.Server httpServer *http.Server
loggingEnabled bool loggingEnabled bool
debugMode bool // Controls whether to show error details
errorConfig utils.ErrorPageConfig
} }
// New creates a new HTTP server with optimized connection settings // New creates a new HTTP server with optimized connection settings
func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, runner *runner.LuaRunner, log *logger.Logger, loggingEnabled bool) *Server { func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter,
runner *runner.LuaRunner, log *logger.Logger,
loggingEnabled bool, debugMode bool, overrideDir string) *Server {
server := &Server{ server := &Server{
luaRouter: luaRouter, luaRouter: luaRouter,
staticRouter: staticRouter, staticRouter: staticRouter,
@ -31,6 +37,11 @@ func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, runne
logger: log, logger: log,
httpServer: &http.Server{}, httpServer: &http.Server{},
loggingEnabled: loggingEnabled, loggingEnabled: loggingEnabled,
debugMode: debugMode,
errorConfig: utils.ErrorPageConfig{
OverrideDir: overrideDir,
DebugMode: debugMode,
},
} }
server.httpServer.Handler = server server.httpServer.Handler = server
@ -99,8 +110,17 @@ func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) {
return return
} }
// No route found // No route found - 404 Not Found
http.NotFound(w, r) w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(utils.NotFoundPage(s.errorConfig, r.URL.Path)))
}
// HandleMethodNotAllowed responds with a 405 Method Not Allowed error
func (s *Server) HandleMethodNotAllowed(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte(utils.MethodNotAllowedPage(s.errorConfig, r.URL.Path)))
} }
// handleLuaRoute executes a Lua route // handleLuaRoute executes a Lua route
@ -135,9 +155,13 @@ func (s *Server) handleLuaRoute(w http.ResponseWriter, r *http.Request, bytecode
ctx.Set("params", paramMap) ctx.Set("params", paramMap)
} }
// Query parameters will be parsed lazily via metatable in Lua // Parse query parameters only if present
// Instead of parsing for every request, we'll pass the raw URL queryMap := QueryToLua(r)
ctx.Set("rawQuery", r.URL.RawQuery) if queryMap == nil {
ctx.Set("query", make(map[string]any))
} else {
ctx.Set("query", queryMap)
}
// Add form data for POST/PUT/PATCH only when needed // Add form data for POST/PUT/PATCH only when needed
if r.Method == http.MethodPost || r.Method == http.MethodPut || r.Method == http.MethodPatch { if r.Method == http.MethodPost || r.Method == http.MethodPut || r.Method == http.MethodPatch {
@ -150,7 +174,15 @@ func (s *Server) handleLuaRoute(w http.ResponseWriter, r *http.Request, bytecode
result, err := s.luaRunner.Run(bytecode, ctx, scriptPath) result, err := s.luaRunner.Run(bytecode, ctx, scriptPath)
if err != nil { if err != nil {
s.logger.Error("Error executing Lua route: %v", err) s.logger.Error("Error executing Lua route: %v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
// Set content type to HTML
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
// Generate error page with error message
errorMsg := err.Error()
errorHTML := utils.InternalErrorPage(s.errorConfig, r.URL.Path, errorMsg)
w.Write([]byte(errorHTML))
return return
} }

View File

@ -60,6 +60,7 @@ func (s *Sandbox) Setup(state *luajit.State) error {
} }
-- Basic functions -- Basic functions
base.print = print
base.tonumber = tonumber base.tonumber = tonumber
base.tostring = tostring base.tostring = tostring
base.type = type base.type = type

View File

@ -132,8 +132,14 @@ func main() {
port := cfg.GetInt("port", 3117) port := cfg.GetInt("port", 3117)
routesDir := cfg.GetString("routes_dir", "./routes") routesDir := cfg.GetString("routes_dir", "./routes")
staticDir := cfg.GetString("static_dir", "./static") staticDir := cfg.GetString("static_dir", "./static")
overrideDir := cfg.GetString("override_dir", "./override")
bufferSize := cfg.GetInt("buffer_size", 20) bufferSize := cfg.GetInt("buffer_size", 20)
if err := utils.EnsureDir(overrideDir); err != nil {
log.Warning("Override directory doesn't exist, and could not create it: %v", err)
overrideDir = "" // Disable overrides if directory can't be created
}
// Get library directories // Get library directories
var libDirs []string var libDirs []string
libDirsConfig := cfg.GetStringArray("lib_dirs") libDirsConfig := cfg.GetStringArray("lib_dirs")
@ -215,8 +221,10 @@ func main() {
log.Info("HTTP logging is disabled") log.Info("HTTP logging is disabled")
} }
debugMode := cfg.GetBool("debug", false)
// Create HTTP server // Create HTTP server
server := http.New(luaRouter, staticRouter, luaRunner, log, httpLoggingEnabled) server := http.New(luaRouter, staticRouter, luaRunner, log, httpLoggingEnabled, debugMode, overrideDir)
// Handle graceful shutdown // Handle graceful shutdown
stop := make(chan os.Signal, 1) stop := make(chan os.Signal, 1)