Add theme-specific error page

This commit is contained in:
Drew DeVault 2020-11-19 10:09:05 -05:00
parent 5087e4b327
commit 1992880454
7 changed files with 59 additions and 14 deletions

View File

@ -70,9 +70,6 @@ func main() {
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: "${time_rfc3339} method=${method}, uri=${uri}, status=${status}\n", Format: "${time_rfc3339} method=${method}, uri=${uri}, status=${status}\n",
})) }))
}
if options.Debug {
e.Logger.SetLevel(log.DEBUG) e.Logger.SetLevel(log.DEBUG)
} }

View File

@ -118,7 +118,7 @@ func newIMAPBaseRenderData(ctx *alps.Context,
} }
if mboxName != "" { if mboxName != "" {
if active, err = getMailboxStatus(c, mboxName); err != nil { if active, err = getMailboxStatus(c, mboxName); err != nil {
return err return echo.NewHTTPError(http.StatusNotFound, err)
} }
} }
if mboxName == "INBOX" { if mboxName == "INBOX" {

View File

@ -70,14 +70,19 @@ type RenderData interface {
// BaseRenderData: *alps.NewBaseRenderData(ctx), // BaseRenderData: *alps.NewBaseRenderData(ctx),
// // other fields... // // other fields...
// } // }
func NewBaseRenderData(ctx *Context) *BaseRenderData { func NewBaseRenderData(ectx echo.Context) *BaseRenderData {
ctx, isactx := ectx.(*Context)
global := GlobalRenderData{ global := GlobalRenderData{
Extra: make(map[string]interface{}), Extra: make(map[string]interface{}),
Path: strings.Split(ctx.Request().URL.Path, "/")[1:], Path: strings.Split(ectx.Request().URL.Path, "/")[1:],
Title: "Webmail", Title: "Webmail",
URL: ctx.Request().URL, URL: ectx.Request().URL,
HavePlugin: func(name string) bool { HavePlugin: func(name string) bool {
if !isactx {
return false
}
for _, plugin := range ctx.Server.plugins { for _, plugin := range ctx.Server.plugins {
if plugin.Name() == name { if plugin.Name() == name {
return true return true
@ -87,7 +92,7 @@ func NewBaseRenderData(ctx *Context) *BaseRenderData {
}, },
} }
if ctx.Session != nil { if isactx && ctx.Session != nil {
global.LoggedIn = true global.LoggedIn = true
global.Username = ctx.Session.username global.Username = ctx.Session.username
} }

View File

@ -382,15 +382,31 @@ func New(e *echo.Echo, options *Options) (*Server, error) {
return nil, err return nil, err
} }
e.HTTPErrorHandler = func(err error, c echo.Context) { e.HTTPErrorHandler = func(err error, ctx echo.Context) {
code := http.StatusInternalServerError code := http.StatusInternalServerError
if he, ok := err.(*echo.HTTPError); ok { if he, ok := err.(*echo.HTTPError); ok {
code = he.Code code = he.Code
} else {
c.Logger().Error(err)
} }
// TODO: hide internal errors
c.String(code, err.Error()) type ErrorRenderData struct {
BaseRenderData
Code int
Err error
Status string
}
rdata := ErrorRenderData{
BaseRenderData: *NewBaseRenderData(ctx),
Err: err,
Code: code,
Status: http.StatusText(code),
}
if err := ctx.Render(code, "error.html", &rdata); err != nil {
ctx.Logger().Error(fmt.Errorf(
"Error occured rendering error page: %w. How meta.", err))
}
ctx.Logger().Error(err)
} }
e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc {

View File

@ -123,8 +123,19 @@ footer { text-align: right; }
.actions { padding: 0.5rem; } .actions { padding: 0.5rem; }
.container { flex: 1 auto; display: flex; flex-direction: column; flex-wrap: nowrap; min-width: 0; } .container {
flex: 1 auto;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
min-width: 0;
}
.container.error {
max-width: 800px;
margin: 0 auto;
padding: 1rem 0;
}
aside { flex: 0 0 180px; } aside { flex: 0 0 180px; }

14
themes/alps/error.html Normal file
View File

@ -0,0 +1,14 @@
{{template "head.html" .}}
<div class="page-wrap">
<div class="container error">
<h1>{{.Code}}: {{.Status}}</h1>
<p>
An error occured. You can try
<a href="/">returning to your inbox</a>,
or contact support.
</p>
</div>
</div>
{{template "foot.html"}}

View File

@ -22,10 +22,12 @@
{{ end }} {{ end }}
>Contacts</a> >Contacts</a>
{{ end }} {{ end }}
{{ if .GlobalData.LoggedIn }}
<div> <div>
<span>{{ .GlobalData.Username }}</span> <span>{{ .GlobalData.Username }}</span>
<a href="/settings">Settings</a> <a href="/settings">Settings</a>
<a href="/logout">Sign Out</a> <a href="/logout">Sign Out</a>
</div> </div>
{{ end }}
</nav> </nav>
</header> </header>