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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.erbosoft.com/amy/amsterdam/ui"
|
"git.erbosoft.com/amy/amsterdam/ui"
|
||||||
@@ -42,7 +43,6 @@ var EPARAM error = errors.New("no parameters specified")
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Command string dictating what to be rendered.
|
* Command string dictating what to be rendered.
|
||||||
* Data as a parameter for the command string.
|
* Data as a parameter for the command string.
|
||||||
* Standard Go error status.
|
|
||||||
*/
|
*/
|
||||||
func NotImplPage(ctxt ui.AmContext) (string, any) {
|
func NotImplPage(ctxt ui.AmContext) (string, any) {
|
||||||
ctxt.SetLeftMenu("top")
|
ctxt.SetLeftMenu("top")
|
||||||
@@ -51,17 +51,31 @@ func NotImplPage(ctxt ui.AmContext) (string, any) {
|
|||||||
return "framed", "notimpl.jet"
|
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.
|
/* AmErrorHandler handles all the mundane HTTP errors generated by the Echo engine.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* err - The error to be handled.
|
* err - The error to be handled.
|
||||||
* c - The Echo context error is being handled on.
|
* c - The Echo context error is being handled on.
|
||||||
*/
|
*/
|
||||||
func AmErrorHandler(err error, c echo.Context) {
|
func AmErrorHandler(err error, c echo.Context) {
|
||||||
|
log.Infof("-> AmErrorHandler on path %s", c.Request().URL.Path)
|
||||||
if c.Response().Committed {
|
if c.Response().Committed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
amctxt := ui.AmContextFromEchoContext(c)
|
cerr := ui.AmWithTempContext(c, func(ctxt ui.AmContext) (string, any) {
|
||||||
cerr := ui.AmSendPageData(c, amctxt, "error", err)
|
return "error", err
|
||||||
|
})
|
||||||
if cerr != nil {
|
if cerr != nil {
|
||||||
log.Errorf("Error rendering error (%v): %v", err, cerr)
|
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.
|
// 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}
|
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.Match(GetAndPost, "/TODO/*", ui.AmWrap(NotImplPage), uiset...)
|
||||||
e.GET("/img/*", ui.AmServeImage)
|
e.GET("/img/*", ui.AmServeImage)
|
||||||
e.GET("/static/*", ui.AmStaticFileHandler())
|
e.GET("/static/*", ui.AmStaticFileHandler())
|
||||||
|
|||||||
+26
-23
@@ -549,34 +549,37 @@ func newContext(ctxt echo.Context) (*amContext, error) {
|
|||||||
|
|
||||||
rc.echoContext = ctxt
|
rc.echoContext = ctxt
|
||||||
ctxt.Set("__amsterdam_context", rc)
|
ctxt.Set("__amsterdam_context", rc)
|
||||||
store := ctxt.Get("AmSessionStore").(AmSessionStore)
|
stmp := ctxt.Get("AmSessionStore")
|
||||||
sess, err := store.Get(ctxt.Request(), "AMSTERDAM_SESSION")
|
if stmp != nil {
|
||||||
if err == nil {
|
store := stmp.(AmSessionStore)
|
||||||
rc.session = sess
|
sess, err := store.Get(ctxt.Request(), "AMSTERDAM_SESSION")
|
||||||
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 {
|
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 {
|
} else {
|
||||||
rc.user = nil
|
rc.user = nil
|
||||||
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
||||||
}
|
}
|
||||||
} else {
|
if rc.user != nil && !rc.user.IsAnon {
|
||||||
rc.user = nil
|
cp, ok := sess.Get("lastCommunity")
|
||||||
rc.effectiveLevel = database.AmRole("NotInList").Level()
|
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
|
return rc, err
|
||||||
|
|||||||
+46
-4
@@ -114,11 +114,16 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
|
|||||||
case "top":
|
case "top":
|
||||||
menus[0] = AmMenu("top")
|
menus[0] = AmMenu("top")
|
||||||
case "community":
|
case "community":
|
||||||
md, err := AmBuildCommunityMenu(ctxt.Request().Context(), amctxt.CurrentCommunity())
|
comm := amctxt.CurrentCommunity()
|
||||||
if err != nil {
|
if comm != nil {
|
||||||
return err
|
md, err := AmBuildCommunityMenu(ctxt.Request().Context(), comm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
menus[0] = md
|
||||||
|
} else {
|
||||||
|
menus[0] = AmMenu("top")
|
||||||
}
|
}
|
||||||
menus[0] = md
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("AmSendPageData(): unknown left menu context: %s", amctxt.LeftMenu())
|
return fmt.Errorf("AmSendPageData(): unknown left menu context: %s", amctxt.LeftMenu())
|
||||||
}
|
}
|
||||||
@@ -175,3 +180,40 @@ func AmWrap(myfunc AmPageFunc) echo.HandlerFunc {
|
|||||||
return nil
|
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