Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
张磊
/
FileStorageBeego
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
3aceaf88
authored
2015-02-26 23:34:43 +0800
by
astaxie
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
error support controller
1 parent
71b9854f
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
136 additions
and
139 deletions
beego.go
config.go
context/context.go
middleware/error.go → error.go
middleware/exceptions.go
namespace.go
router.go
staticfile.go
beego.go
View file @
3aceaf8
...
...
@@ -33,7 +33,6 @@ import (
"strconv"
"strings"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/session"
)
...
...
@@ -280,15 +279,6 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
return
BeeApp
}
// ErrorHandler registers http.HandlerFunc to each http err code string.
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
func
Errorhandler
(
err
string
,
h
http
.
HandlerFunc
)
*
App
{
middleware
.
Errorhandler
(
err
,
h
)
return
BeeApp
}
// SetViewsPath sets view directory path in beego application.
func
SetViewsPath
(
path
string
)
*
App
{
ViewsPath
=
path
...
...
@@ -402,9 +392,7 @@ func initBeforeHttpRun() {
}
}
middleware
.
VERSION
=
VERSION
middleware
.
AppName
=
AppName
middleware
.
RegisterErrorHandler
()
registerDefaultErrorHandler
()
if
EnableDocs
{
Get
(
"/docs"
,
serverDocs
)
...
...
config.go
View file @
3aceaf8
...
...
@@ -81,6 +81,7 @@ var (
AppConfigProvider
string
// config provider
EnableDocs
bool
// enable generate docs & server docs API Swagger
RouterCaseSensitive
bool
// router case sensitive default is true
AccessLogs
bool
// print access logs, default is false
)
type
beegoAppConfig
struct
{
...
...
context/context.go
View file @
3aceaf8
...
...
@@ -31,7 +31,7 @@ import (
"strings"
"time"
"github.com/astaxie/beego
/middleware
"
"github.com/astaxie/beego"
"github.com/astaxie/beego/utils"
)
...
...
@@ -53,24 +53,16 @@ func (ctx *Context) Redirect(status int, localurl string) {
}
// Abort stops this request.
// if middleware.ErrorMaps exists, panic body.
// if middleware.HTTPExceptionMaps exists, panic HTTPException struct with status and body string.
// if beego.ErrorMaps exists, panic body.
func
(
ctx
*
Context
)
Abort
(
status
int
,
body
string
)
{
ctx
.
ResponseWriter
.
WriteHeader
(
status
)
// first panic from ErrorMaps, is is user defined error functions.
if
_
,
ok
:=
middleware
.
ErrorMaps
[
body
];
ok
{
if
_
,
ok
:=
beego
.
ErrorMaps
[
body
];
ok
{
panic
(
body
)
}
// second panic from HTTPExceptionMaps, it is system defined functions.
if
e
,
ok
:=
middleware
.
HTTPExceptionMaps
[
status
];
ok
{
if
len
(
body
)
>=
1
{
e
.
Description
=
body
}
panic
(
e
)
}
// last panic user string
ctx
.
ResponseWriter
.
Write
([]
byte
(
body
))
panic
(
"User stop run"
)
panic
(
beego
.
USERSTOPRUN
)
}
// Write string to response body.
...
...
middleware/
error.go
→
error.go
View file @
3aceaf8
...
...
@@ -12,20 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package
middleware
package
beego
import
(
"fmt"
"html/template"
"net/http"
"reflect"
"runtime"
"strconv"
"strings"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/utils"
)
var
(
AppName
string
VERSION
string
const
(
errorTypeHandler
=
iota
errorTypeController
)
var
tpl
=
`
<!DOCTYPE html>
<html>
...
...
@@ -76,18 +82,18 @@ var tpl = `
`
// render default application error page with error and stack string.
func
ShowErr
(
err
interface
{},
rw
http
.
ResponseWriter
,
r
*
http
.
Reques
t
,
Stack
string
)
{
func
showErr
(
err
interface
{},
ctx
*
context
.
Contex
t
,
Stack
string
)
{
t
,
_
:=
template
.
New
(
"beegoerrortemp"
)
.
Parse
(
tpl
)
data
:=
make
(
map
[
string
]
string
)
data
[
"AppError"
]
=
AppName
+
":"
+
fmt
.
Sprint
(
err
)
data
[
"RequestMethod"
]
=
r
.
Method
data
[
"RequestURL"
]
=
r
.
RequestURI
data
[
"RemoteAddr"
]
=
r
.
RemoteAddr
data
[
"RequestMethod"
]
=
ctx
.
Input
.
Method
()
data
[
"RequestURL"
]
=
ctx
.
Input
.
Uri
()
data
[
"RemoteAddr"
]
=
ctx
.
Input
.
IP
()
data
[
"Stack"
]
=
Stack
data
[
"BeegoVersion"
]
=
VERSION
data
[
"GoVersion"
]
=
runtime
.
Version
()
rw
.
WriteHeader
(
500
)
t
.
Execute
(
rw
,
data
)
ctx
.
Output
.
SetStatus
(
500
)
t
.
Execute
(
ctx
.
ResponseWriter
,
data
)
}
var
errtpl
=
`
...
...
@@ -190,11 +196,18 @@ var errtpl = `
</html>
`
type
errorInfo
struct
{
controllerType
reflect
.
Type
handler
http
.
HandlerFunc
method
string
errorType
int
}
// map of http handlers for each error string.
var
ErrorMaps
map
[
string
]
http
.
HandlerFunc
var
ErrorMaps
map
[
string
]
*
errorInfo
func
init
()
{
ErrorMaps
=
make
(
map
[
string
]
http
.
HandlerFunc
)
ErrorMaps
=
make
(
map
[
string
]
*
errorInfo
)
}
// show 404 notfound error.
...
...
@@ -283,55 +296,115 @@ func SimpleServerError(rw http.ResponseWriter, r *http.Request) {
http
.
Error
(
rw
,
http
.
StatusText
(
http
.
StatusInternalServerError
),
http
.
StatusInternalServerError
)
}
// add http handler for given error string.
func
Errorhandler
(
err
string
,
h
http
.
HandlerFunc
)
{
ErrorMaps
[
err
]
=
h
}
// register default error http handlers, 404,401,403,500 and 503.
func
Register
ErrorHandler
()
{
func
registerDefault
ErrorHandler
()
{
if
_
,
ok
:=
ErrorMaps
[
"404"
];
!
ok
{
Error
Maps
[
"404"
]
=
NotFound
Error
handler
(
"404"
,
NotFound
)
}
if
_
,
ok
:=
ErrorMaps
[
"401"
];
!
ok
{
Error
Maps
[
"401"
]
=
Unauthorized
Error
handler
(
"401"
,
Unauthorized
)
}
if
_
,
ok
:=
ErrorMaps
[
"403"
];
!
ok
{
Error
Maps
[
"403"
]
=
Forbidden
Error
handler
(
"403"
,
Forbidden
)
}
if
_
,
ok
:=
ErrorMaps
[
"503"
];
!
ok
{
Error
Maps
[
"503"
]
=
ServiceUnavailable
Error
handler
(
"503"
,
ServiceUnavailable
)
}
if
_
,
ok
:=
ErrorMaps
[
"500"
];
!
ok
{
Error
Maps
[
"500"
]
=
InternalServerError
Error
handler
(
"500"
,
InternalServerError
)
}
}
// ErrorHandler registers http.HandlerFunc to each http err code string.
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
func
Errorhandler
(
code
string
,
h
http
.
HandlerFunc
)
*
App
{
errinfo
:=
&
errorInfo
{}
errinfo
.
errorType
=
errorTypeHandler
errinfo
.
handler
=
h
errinfo
.
method
=
code
ErrorMaps
[
code
]
=
errinfo
return
BeeApp
}
// ErrorController registers ControllerInterface to each http err code string.
// usage:
// beego.ErrorHandler(&controllers.ErrorController{})
func
ErrorController
(
c
ControllerInterface
)
*
App
{
reflectVal
:=
reflect
.
ValueOf
(
c
)
rt
:=
reflectVal
.
Type
()
ct
:=
reflect
.
Indirect
(
reflectVal
)
.
Type
()
for
i
:=
0
;
i
<
rt
.
NumMethod
();
i
++
{
if
!
utils
.
InSlice
(
rt
.
Method
(
i
)
.
Name
,
exceptMethod
)
&&
strings
.
HasPrefix
(
rt
.
Method
(
i
)
.
Name
,
"Error"
)
{
errinfo
:=
&
errorInfo
{}
errinfo
.
errorType
=
errorTypeController
errinfo
.
controllerType
=
ct
errinfo
.
method
=
rt
.
Method
(
i
)
.
Name
errname
:=
strings
.
TrimPrefix
(
rt
.
Method
(
i
)
.
Name
,
"Error"
)
ErrorMaps
[
errname
]
=
errinfo
}
}
return
BeeApp
}
// show error string as simple text message.
// if error string is empty, show 500 error as default.
func
Exception
(
errcode
string
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
msg
string
)
{
if
h
,
ok
:=
ErrorMaps
[
errcode
];
ok
{
isint
,
err
:=
strconv
.
Atoi
(
errcode
)
func
exception
(
errcode
string
,
ctx
*
context
.
Context
)
{
code
,
err
:=
strconv
.
Atoi
(
errcode
)
if
err
!=
nil
{
isint
=
500
code
=
503
}
w
.
Header
()
.
Set
(
"Content-Type"
,
"text/html; charset=utf-8"
)
w
.
WriteHeader
(
isint
)
h
(
w
,
r
)
ctx
.
ResponseWriter
.
WriteHeader
(
code
)
if
h
,
ok
:=
ErrorMaps
[
errcode
];
ok
{
executeError
(
h
,
ctx
)
return
}
else
if
h
,
ok
:=
ErrorMaps
[
"503"
];
ok
{
executeError
(
h
,
ctx
)
return
}
else
{
ctx
.
WriteString
(
errcode
)
}
isint
,
err
:=
strconv
.
Atoi
(
errcode
)
if
err
!=
nil
{
isint
=
500
}
func
executeError
(
err
*
errorInfo
,
ctx
*
context
.
Context
)
{
if
err
.
errorType
==
errorTypeHandler
{
err
.
handler
(
ctx
.
ResponseWriter
,
ctx
.
Request
)
return
}
if
err
.
errorType
==
errorTypeController
{
//Invoke the request handler
vc
:=
reflect
.
New
(
err
.
controllerType
)
execController
,
ok
:=
vc
.
Interface
()
.
(
ControllerInterface
)
if
!
ok
{
panic
(
"controller is not ControllerInterface"
)
}
//call the controller init function
execController
.
Init
(
ctx
,
err
.
controllerType
.
Name
(),
err
.
method
,
vc
.
Interface
())
//call prepare function
execController
.
Prepare
()
execController
.
URLMapping
()
in
:=
make
([]
reflect
.
Value
,
0
)
method
:=
vc
.
MethodByName
(
err
.
method
)
method
.
Call
(
in
)
//render template
if
ctx
.
Output
.
Status
==
0
{
if
AutoRender
{
if
err
:=
execController
.
Render
();
err
!=
nil
{
panic
(
err
)
}
if
isint
==
404
{
msg
=
"404 page not found"
}
w
.
Header
()
.
Set
(
"Content-Type"
,
"text/plain; charset=utf-8"
)
w
.
WriteHeader
(
isint
)
fmt
.
Fprintln
(
w
,
msg
)
}
// finish all runrouter. release resource
execController
.
Finish
()
}
}
...
...
middleware/exceptions.go
deleted
100644 → 0
View file @
71b9854
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package
middleware
import
"fmt"
// http exceptions
type
HTTPException
struct
{
StatusCode
int
// http status code 4xx, 5xx
Description
string
}
// return http exception error string, e.g. "400 Bad Request".
func
(
e
*
HTTPException
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%d %s"
,
e
.
StatusCode
,
e
.
Description
)
}
// map of http exceptions for each http status code int.
// defined 400,401,403,404,405,500,502,503 and 504 default.
var
HTTPExceptionMaps
map
[
int
]
HTTPException
func
init
()
{
HTTPExceptionMaps
=
make
(
map
[
int
]
HTTPException
)
// Normal 4XX HTTP Status
HTTPExceptionMaps
[
400
]
=
HTTPException
{
400
,
"Bad Request"
}
HTTPExceptionMaps
[
401
]
=
HTTPException
{
401
,
"Unauthorized"
}
HTTPExceptionMaps
[
403
]
=
HTTPException
{
403
,
"Forbidden"
}
HTTPExceptionMaps
[
404
]
=
HTTPException
{
404
,
"Not Found"
}
HTTPExceptionMaps
[
405
]
=
HTTPException
{
405
,
"Method Not Allowed"
}
// Normal 5XX HTTP Status
HTTPExceptionMaps
[
500
]
=
HTTPException
{
500
,
"Internal Server Error"
}
HTTPExceptionMaps
[
502
]
=
HTTPException
{
502
,
"Bad Gateway"
}
HTTPExceptionMaps
[
503
]
=
HTTPException
{
503
,
"Service Unavailable"
}
HTTPExceptionMaps
[
504
]
=
HTTPException
{
504
,
"Gateway Timeout"
}
}
namespace.go
View file @
3aceaf8
...
...
@@ -19,7 +19,6 @@ import (
"strings"
beecontext
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
)
type
namespaceCond
func
(
*
beecontext
.
Context
)
bool
...
...
@@ -57,7 +56,7 @@ func NewNamespace(prefix string, params ...innnerNamespace) *Namespace {
func
(
n
*
Namespace
)
Cond
(
cond
namespaceCond
)
*
Namespace
{
fn
:=
func
(
ctx
*
beecontext
.
Context
)
{
if
!
cond
(
ctx
)
{
middleware
.
Exception
(
"405"
,
ctx
.
ResponseWriter
,
ctx
.
Request
,
"Method not allowed"
)
exception
(
"405"
,
ctx
)
}
}
if
v
,
ok
:=
n
.
handlers
.
filters
[
BeforeRouter
];
ok
{
...
...
router.go
View file @
3aceaf8
...
...
@@ -30,7 +30,6 @@ import (
"time"
beecontext
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/toolbox"
"github.com/astaxie/beego/utils"
)
...
...
@@ -577,7 +576,6 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin
// Implement http.Handler interface.
func
(
p
*
ControllerRegistor
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
defer
p
.
recoverPanic
(
rw
,
r
)
starttime
:=
time
.
Now
()
var
runrouter
reflect
.
Type
var
findrouter
bool
...
...
@@ -600,6 +598,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context
.
Output
.
Context
=
context
context
.
Output
.
EnableGzip
=
EnableGzip
defer
p
.
recoverPanic
(
context
)
var
urlPath
string
if
!
RouterCaseSensitive
{
urlPath
=
strings
.
ToLower
(
r
.
URL
.
Path
)
...
...
@@ -648,7 +648,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context
.
Input
.
CruSession
,
err
=
GlobalSessions
.
SessionStart
(
w
,
r
)
if
err
!=
nil
{
Error
(
err
)
middleware
.
Exception
(
"503"
,
rw
,
r
,
""
)
exception
(
"503"
,
context
)
return
}
defer
func
()
{
...
...
@@ -703,7 +703,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
//if no matches to url, throw a not found exception
if
!
findrouter
{
middleware
.
Exception
(
"404"
,
rw
,
r
,
""
)
exception
(
"404"
,
context
)
goto
Admin
}
...
...
@@ -719,7 +719,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
isRunable
=
true
routerInfo
.
runfunction
(
context
)
}
else
{
middleware
.
Exception
(
"405"
,
rw
,
r
,
"Method Not Allowed"
)
exception
(
"405"
,
context
)
goto
Admin
}
}
else
if
routerInfo
.
routerType
==
routerTypeHandler
{
...
...
@@ -830,7 +830,7 @@ Admin:
}
}
if
RunMode
==
"dev"
{
if
RunMode
==
"dev"
||
AccessLogs
{
var
devinfo
string
if
findrouter
{
if
routerInfo
!=
nil
{
...
...
@@ -852,27 +852,23 @@ Admin:
}
}
func
(
p
*
ControllerRegistor
)
recoverPanic
(
rw
http
.
ResponseWriter
,
r
*
http
.
Reques
t
)
{
func
(
p
*
ControllerRegistor
)
recoverPanic
(
context
*
beecontext
.
Contex
t
)
{
if
err
:=
recover
();
err
!=
nil
{
if
err
==
USERSTOPRUN
{
return
}
if
he
,
ok
:=
err
.
(
middleware
.
HTTPException
);
ok
{
rw
.
Write
([]
byte
(
he
.
Description
))
// catch intented errors, only for HTTP 4XX and 5XX
}
else
{
if
RunMode
==
"dev"
{
if
!
RecoverPanic
{
panic
(
err
)
}
else
{
if
ErrorsShow
{
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
handler
(
rw
,
r
)
if
handler
,
ok
:=
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
executeError
(
handler
,
context
)
return
}
}
var
stack
string
Critical
(
"the request url is "
,
r
.
URL
.
Path
)
Critical
(
"the request url is "
,
context
.
Input
.
Url
()
)
Critical
(
"Handler crashed with error"
,
err
)
for
i
:=
1
;
;
i
++
{
_
,
file
,
line
,
ok
:=
runtime
.
Caller
(
i
)
...
...
@@ -882,7 +878,7 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques
Critical
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
stack
=
stack
+
fmt
.
Sprintln
(
fmt
.
Sprintf
(
"%s:%d"
,
file
,
line
))
}
middleware
.
ShowErr
(
err
,
rw
,
r
,
stack
)
showErr
(
err
,
context
,
stack
)
}
}
else
{
if
!
RecoverPanic
{
...
...
@@ -890,17 +886,17 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques
}
else
{
// in production model show all infomation
if
ErrorsShow
{
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
handler
(
rw
,
r
)
if
handler
,
ok
:=
ErrorMaps
[
fmt
.
Sprint
(
err
)];
ok
{
executeError
(
handler
,
context
)
return
}
else
if
handler
,
ok
:=
middleware
.
ErrorMaps
[
"503"
];
ok
{
handler
(
rw
,
r
)
}
else
if
handler
,
ok
:=
ErrorMaps
[
"503"
];
ok
{
executeError
(
handler
,
context
)
return
}
else
{
rw
.
Write
([]
byte
(
fmt
.
Sprint
(
err
)
))
context
.
WriteString
(
fmt
.
Sprint
(
err
))
}
}
else
{
Critical
(
"the request url is "
,
r
.
URL
.
Path
)
Critical
(
"the request url is "
,
context
.
Input
.
Url
()
)
Critical
(
"Handler crashed with error"
,
err
)
for
i
:=
1
;
;
i
++
{
_
,
file
,
line
,
ok
:=
runtime
.
Caller
(
i
)
...
...
@@ -912,8 +908,6 @@ func (p *ControllerRegistor) recoverPanic(rw http.ResponseWriter, r *http.Reques
}
}
}
}
}
}
...
...
staticfile.go
View file @
3aceaf8
...
...
@@ -22,7 +22,6 @@ import (
"strings"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/utils"
)
...
...
@@ -67,7 +66,7 @@ func serverStaticRouter(ctx *context.Context) {
//if the request is dir and DirectoryIndex is false then
if
finfo
.
IsDir
()
{
if
!
DirectoryIndex
{
middleware
.
Exception
(
"403"
,
ctx
.
ResponseWriter
,
ctx
.
Request
,
"403 Forbidden"
)
exception
(
"403"
,
ctx
)
return
}
else
if
ctx
.
Input
.
Request
.
URL
.
Path
[
len
(
ctx
.
Input
.
Request
.
URL
.
Path
)
-
1
]
!=
'/'
{
http
.
Redirect
(
ctx
.
ResponseWriter
,
ctx
.
Request
,
ctx
.
Input
.
Request
.
URL
.
Path
+
"/"
,
302
)
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment