[Redbean] Feature / OnError(status, message) hook (#1103)

This commit is contained in:
BONNAURE Olivier 2024-02-14 10:55:50 +01:00 committed by GitHub
parent 2ab9e9f7fd
commit d3ff48c63f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 114 additions and 77 deletions

View file

@ -550,6 +550,17 @@ SPECIAL PATHS
---
function OnHttpRequest() end
--- Hooks catch errors
---
--- If this functiopn is defined in the global scope by your `/.init.lua`
--- then any errors occuring in the OnHttpRequest() hook will be catched.
--- You'll be able then to do whatever you need with the error status and
--- error message.
---
---@param status uint16
---@param message string
function OnError(status, message) end
--- Hooks client connection creation.
---
--- If this function is defined it'll be called from the main process

View file

@ -576,6 +576,12 @@ HOOKS
*). See functions like Route which asks redbean to do its default
thing from the handler.
OnError(status:int, message:string)
If this function is defined and if any errors occurs in
OnHttpRequest() then this method will be called instead of displaying
the default error page. Useful if you need to display the error page
using your specific code or send it to any tier service.
OnClientConnection(ip:int, port:int, serverip:int, serverport:int) → bool
If this function is defined it'll be called from the main process
each time redbean accepts a new client connection. If it returns

View file

@ -456,6 +456,7 @@ static bool isexitingworker;
static bool hasonworkerstart;
static bool leakcrashreports;
static bool hasonhttprequest;
static bool hasonerror;
static bool ishandlingrequest;
static bool listeningonport443;
static bool hasonprocesscreate;
@ -2532,7 +2533,7 @@ img { vertical-align: middle; }\r\n\
return p;
}
static char *ServeErrorImpl(unsigned code, const char *reason,
static char *ServeErrorImplDefault(unsigned code, const char *reason,
const char *details) {
size_t n;
char *p, *s;
@ -2570,6 +2571,28 @@ static char *ServeErrorImpl(unsigned code, const char *reason,
}
}
static char *GetLuaResponse(void) {
return cpm.luaheaderp ? cpm.luaheaderp : SetStatus(200, "OK");
}
static char *ServeErrorImpl(unsigned code, const char *reason,
const char *details) {
lua_State *L = GL;
if (hasonerror) {
lua_getglobal(L, "OnError");
lua_pushinteger(L, code);
lua_pushstring(L, reason);
if (LuaCallWithTrace(L, 2, 0, NULL) == LUA_OK) {
return CommitOutput(GetLuaResponse());
} else {
return ServeErrorImplDefault(code, reason, details);
}
} else {
return ServeErrorImplDefault(code, reason, details);
}
}
static char *ServeErrorWithPath(unsigned code, const char *reason,
const char *path, size_t pathlen) {
ERRORF("(srvr) server error: %d %s %`'.*s", code, reason, pathlen, path);
@ -3227,10 +3250,6 @@ static char *ServeIndex(const char *path, size_t pathlen) {
return p;
}
static char *GetLuaResponse(void) {
return cpm.luaheaderp ? cpm.luaheaderp : SetStatus(200, "OK");
}
static bool ShouldServeCrashReportDetails(void) {
uint32_t ip;
uint16_t port;
@ -5569,6 +5588,7 @@ static void LuaInit(void) {
}
if (LuaRunAsset("/.init.lua", true)) {
hasonhttprequest = IsHookDefined("OnHttpRequest");
hasonerror = IsHookDefined("OnError");
hasonclientconnection = IsHookDefined("OnClientConnection");
hasonprocesscreate = IsHookDefined("OnProcessCreate");
hasonprocessdestroy = IsHookDefined("OnProcessDestroy");