straightened out error handling so we don't wind up with a bunch of panics clogging the debug console
This commit is contained in:
@@ -11,6 +11,7 @@ package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.erbosoft.com/amy/amsterdam/ui"
|
||||
@@ -42,7 +43,6 @@ var EPARAM error = errors.New("no parameters specified")
|
||||
* Returns:
|
||||
* Command string dictating what to be rendered.
|
||||
* Data as a parameter for the command string.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func NotImplPage(ctxt ui.AmContext) (string, any) {
|
||||
ctxt.SetLeftMenu("top")
|
||||
@@ -51,17 +51,31 @@ func NotImplPage(ctxt ui.AmContext) (string, any) {
|
||||
return "framed", "notimpl.jet"
|
||||
}
|
||||
|
||||
/* AmNotFoundHandler handles all paths that are "not found" in the application.
|
||||
* Parameters:
|
||||
* ctxt - The AmContext for the request.
|
||||
* Returns:
|
||||
* Command string dictating what to be rendered.
|
||||
* Data as a parameter for the command string.
|
||||
*/
|
||||
func AmNotFoundHandler(ctxt ui.AmContext) (string, any) {
|
||||
log.Infof("-> AmNotFoundHandler on path %s", ctxt.URLPath())
|
||||
return "error", fmt.Errorf("Path not found: %s", ctxt.URLPath())
|
||||
}
|
||||
|
||||
/* AmErrorHandler handles all the mundane HTTP errors generated by the Echo engine.
|
||||
* Parameters:
|
||||
* err - The error to be handled.
|
||||
* c - The Echo context error is being handled on.
|
||||
*/
|
||||
func AmErrorHandler(err error, c echo.Context) {
|
||||
log.Infof("-> AmErrorHandler on path %s", c.Request().URL.Path)
|
||||
if c.Response().Committed {
|
||||
return
|
||||
}
|
||||
amctxt := ui.AmContextFromEchoContext(c)
|
||||
cerr := ui.AmSendPageData(c, amctxt, "error", err)
|
||||
cerr := ui.AmWithTempContext(c, func(ctxt ui.AmContext) (string, any) {
|
||||
return "error", err
|
||||
})
|
||||
if cerr != nil {
|
||||
log.Errorf("Error rendering error (%v): %v", err, cerr)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ func setupEcho() *echo.Echo {
|
||||
// This is the set of all middleware functions used by the UI, as opposed to other things.
|
||||
uiset := []echo.MiddlewareFunc{ui.SessionStoreInjector, ui.ContextCreator, ui.IPBanTest, ui.CookieLoginTest}
|
||||
|
||||
e.RouteNotFound("/*", ui.AmWrap(AmNotFoundHandler), uiset...)
|
||||
e.Match(GetAndPost, "/TODO/*", ui.AmWrap(NotImplPage), uiset...)
|
||||
e.GET("/img/*", ui.AmServeImage)
|
||||
e.GET("/static/*", ui.AmStaticFileHandler())
|
||||
|
||||
+26
-23
@@ -549,34 +549,37 @@ func newContext(ctxt echo.Context) (*amContext, error) {
|
||||
|
||||
rc.echoContext = ctxt
|
||||
ctxt.Set("__amsterdam_context", rc)
|
||||
store := ctxt.Get("AmSessionStore").(AmSessionStore)
|
||||
sess, err := store.Get(ctxt.Request(), "AMSTERDAM_SESSION")
|
||||
if err == nil {
|
||||
rc.session = sess
|
||||
sess.SetOptions(defoptions)
|
||||
if sess.IsNew() {
|
||||
sess.FirstTime(ctxt.Request().Context())
|
||||
} else {
|
||||
sess.Hit()
|
||||
}
|
||||
}
|
||||
id, ok := sess.Uid()
|
||||
if ok {
|
||||
rc.user, err = database.AmGetUser(ctxt.Request().Context(), id)
|
||||
stmp := ctxt.Get("AmSessionStore")
|
||||
if stmp != nil {
|
||||
store := stmp.(AmSessionStore)
|
||||
sess, err := store.Get(ctxt.Request(), "AMSTERDAM_SESSION")
|
||||
if err == nil {
|
||||
rc.effectiveLevel = rc.user.BaseLevel
|
||||
rc.session = sess
|
||||
sess.SetOptions(defoptions)
|
||||
if sess.IsNew() {
|
||||
sess.FirstTime(ctxt.Request().Context())
|
||||
} else {
|
||||
sess.Hit()
|
||||
}
|
||||
}
|
||||
id, ok := sess.Uid()
|
||||
if ok {
|
||||
rc.user, err = database.AmGetUser(ctxt.Request().Context(), id)
|
||||
if err == nil {
|
||||
rc.effectiveLevel = rc.user.BaseLevel
|
||||
} else {
|
||||
rc.user = nil
|
||||
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
||||
}
|
||||
} else {
|
||||
rc.user = nil
|
||||
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
||||
}
|
||||
} else {
|
||||
rc.user = nil
|
||||
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
||||
}
|
||||
if rc.user != nil && !rc.user.IsAnon {
|
||||
cp, ok := sess.Get("lastCommunity")
|
||||
if ok {
|
||||
rc.SetCommunityContext(fmt.Sprintf("%d", cp))
|
||||
if rc.user != nil && !rc.user.IsAnon {
|
||||
cp, ok := sess.Get("lastCommunity")
|
||||
if ok {
|
||||
rc.SetCommunityContext(fmt.Sprintf("%d", cp))
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc, err
|
||||
|
||||
+46
-4
@@ -114,11 +114,16 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
|
||||
case "top":
|
||||
menus[0] = AmMenu("top")
|
||||
case "community":
|
||||
md, err := AmBuildCommunityMenu(ctxt.Request().Context(), amctxt.CurrentCommunity())
|
||||
if err != nil {
|
||||
return err
|
||||
comm := amctxt.CurrentCommunity()
|
||||
if comm != nil {
|
||||
md, err := AmBuildCommunityMenu(ctxt.Request().Context(), comm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
menus[0] = md
|
||||
} else {
|
||||
menus[0] = AmMenu("top")
|
||||
}
|
||||
menus[0] = md
|
||||
default:
|
||||
return fmt.Errorf("AmSendPageData(): unknown left menu context: %s", amctxt.LeftMenu())
|
||||
}
|
||||
@@ -175,3 +180,40 @@ func AmWrap(myfunc AmPageFunc) echo.HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// AmWithTempContext runs a page function with a temporary context. Used in error handling.
|
||||
func AmWithTempContext(c echo.Context, fn AmPageFunc) error {
|
||||
var ctxt AmContext = nil
|
||||
myctxt := c.Get("__amsterdam_context")
|
||||
if myctxt != nil {
|
||||
ac, ok := myctxt.(*amContext)
|
||||
if ok {
|
||||
ctxt = ac
|
||||
ac.echoContext = c
|
||||
}
|
||||
}
|
||||
if ctxt == nil {
|
||||
ac, err := newContext(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctxt = ac
|
||||
defer func() {
|
||||
amContextRecycleBin <- ac
|
||||
}()
|
||||
}
|
||||
|
||||
// Call the function
|
||||
command, arg := fn(ctxt)
|
||||
|
||||
// Add the dynamic headers.
|
||||
c.Response().Header().Set("Pragma", "No-cache")
|
||||
c.Response().Header().Set("Cache-Control", "no-cache")
|
||||
c.Response().Header().Set("Expires", expireTime)
|
||||
|
||||
if err := AmSendPageData(c, ctxt, command, arg); err != nil {
|
||||
c.Logger().Errorf("Rendering error: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user