fix #16
Showing
5 changed files
with
277 additions
and
2 deletions
| ... | @@ -148,6 +148,11 @@ func RouterHandler(path string, c http.Handler) *App { | ... | @@ -148,6 +148,11 @@ func RouterHandler(path string, c http.Handler) *App { |
| 148 | return BeeApp | 148 | return BeeApp |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | func Errorhandler(err string, h http.HandlerFunc) *App { | ||
| 152 | ErrorMaps[err] = h | ||
| 153 | return BeeApp | ||
| 154 | } | ||
| 155 | |||
| 151 | func SetViewsPath(path string) *App { | 156 | func SetViewsPath(path string) *App { |
| 152 | BeeApp.SetViewsPath(path) | 157 | BeeApp.SetViewsPath(path) |
| 153 | return BeeApp | 158 | return BeeApp |
| ... | @@ -195,5 +200,6 @@ func Run() { | ... | @@ -195,5 +200,6 @@ func Run() { |
| 195 | } | 200 | } |
| 196 | } | 201 | } |
| 197 | runtime.GOMAXPROCS(runtime.NumCPU()) | 202 | runtime.GOMAXPROCS(runtime.NumCPU()) |
| 203 | registerErrorHander() | ||
| 198 | BeeApp.Run() | 204 | BeeApp.Run() |
| 199 | } | 205 | } | ... | ... |
| ... | @@ -192,6 +192,10 @@ func (c *Controller) Redirect(url string, code int) { | ... | @@ -192,6 +192,10 @@ func (c *Controller) Redirect(url string, code int) { |
| 192 | c.Ctx.Redirect(code, url) | 192 | c.Ctx.Redirect(code, url) |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | func (c *Controller) Abort(code string) { | ||
| 196 | panic(code) | ||
| 197 | } | ||
| 198 | |||
| 195 | func (c *Controller) ServeJson() { | 199 | func (c *Controller) ServeJson() { |
| 196 | content, err := json.MarshalIndent(c.Data["json"], "", " ") | 200 | content, err := json.MarshalIndent(c.Data["json"], "", " ") |
| 197 | if err != nil { | 201 | if err != nil { | ... | ... |
| ... | @@ -482,7 +482,58 @@ XML数据直接输出,设置`content-type`为`application/xml`: | ... | @@ -482,7 +482,58 @@ XML数据直接输出,设置`content-type`为`application/xml`: |
| 482 | this.Redirect("/", 302) | 482 | this.Redirect("/", 302) |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | @todo 错误处理还需要后期改进 | 485 | 如何中止此次请求并抛出异常,beego可以在控制器中这操作 |
| 486 | |||
| 487 | func (this *MainController) Get() { | ||
| 488 | this.Abort("401") | ||
| 489 | v := this.GetSession("asta") | ||
| 490 | if v == nil { | ||
| 491 | this.SetSession("asta", int(1)) | ||
| 492 | this.Data["Email"] = 0 | ||
| 493 | } else { | ||
| 494 | this.SetSession("asta", v.(int)+1) | ||
| 495 | this.Data["Email"] = v.(int) | ||
| 496 | } | ||
| 497 | this.TplNames = "index.tpl" | ||
| 498 | } | ||
| 499 | |||
| 500 | 这样`this.Abort("401")`之后的代码不会再执行,而且会默认显示给用户如下页面 | ||
| 501 | |||
| 502 |  | ||
| 503 | |||
| 504 | beego框架默认支持404、401、403、500、503这几种错误的处理。用户可以自定义相应的错误处理,例如下面重新定义404页面: | ||
| 505 | |||
| 506 | func page_not_found(rw http.ResponseWriter, r *http.Request){ | ||
| 507 | t:= template.New("beegoerrortemp").ParseFiles(beego.ViewsPath+"404.html") | ||
| 508 | data :=make(map[string]interface{}) | ||
| 509 | data["content"] = "page not found" | ||
| 510 | t.Execute(rw, data) | ||
| 511 | } | ||
| 512 | |||
| 513 | func main() { | ||
| 514 | beego.Errorhandler("404",PageNotFound) | ||
| 515 | beego.Router("/", &controllers.MainController{}) | ||
| 516 | beego.Run() | ||
| 517 | } | ||
| 518 | |||
| 519 | 我们可以通过自定义错误页面`404.html`来处理404错误。 | ||
| 520 | |||
| 521 | beego更加人性化的还有一个设计就是支持用户自定义字符串错误类型处理函数,例如下面的代码,用户注册了一个数据库出错的处理页面: | ||
| 522 | |||
| 523 | func dbError(rw http.ResponseWriter, r *http.Request){ | ||
| 524 | t:= template.New("beegoerrortemp").ParseFiles(beego.ViewsPath+"dberror.html") | ||
| 525 | data :=make(map[string]interface{}) | ||
| 526 | data["content"] = "database is now down" | ||
| 527 | t.Execute(rw, data) | ||
| 528 | } | ||
| 529 | |||
| 530 | func main() { | ||
| 531 | beego.Errorhandler("dbError",dbError) | ||
| 532 | beego.Router("/", &controllers.MainController{}) | ||
| 533 | beego.Run() | ||
| 534 | } | ||
| 535 | |||
| 536 | 一旦在入口注册该错误处理代码,那么你可以在任何你的逻辑中遇到数据库错误调用`this.Abort("dbError")`来进行异常页面处理。 | ||
| 486 | 537 | ||
| 487 | ## response处理 | 538 | ## response处理 |
| 488 | response可能会有集中情况: | 539 | response可能会有集中情况: | ... | ... |
| ... | @@ -57,7 +57,7 @@ var tpl = ` | ... | @@ -57,7 +57,7 @@ var tpl = ` |
| 57 | ` | 57 | ` |
| 58 | 58 | ||
| 59 | func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) { | 59 | func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) { |
| 60 | t, err := template.New("beegoerrortemp").Parse(tpl) | 60 | t, _ := template.New("beegoerrortemp").Parse(tpl) |
| 61 | data := make(map[string]string) | 61 | data := make(map[string]string) |
| 62 | data["AppError"] = AppName + ":" + fmt.Sprint(err) | 62 | data["AppError"] = AppName + ":" + fmt.Sprint(err) |
| 63 | data["RequestMethod"] = r.Method | 63 | data["RequestMethod"] = r.Method |
| ... | @@ -68,3 +68,208 @@ func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack str | ... | @@ -68,3 +68,208 @@ func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack str |
| 68 | data["GoVersion"] = runtime.Version() | 68 | data["GoVersion"] = runtime.Version() |
| 69 | t.Execute(rw, data) | 69 | t.Execute(rw, data) |
| 70 | } | 70 | } |
| 71 | |||
| 72 | var errtpl = ` | ||
| 73 | <!DOCTYPE html> | ||
| 74 | <html lang="en"> | ||
| 75 | <head> | ||
| 76 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | ||
| 77 | <title>Page Not Found</title> | ||
| 78 | <style type="text/css"> | ||
| 79 | * { | ||
| 80 | margin:0; | ||
| 81 | padding:0; | ||
| 82 | } | ||
| 83 | |||
| 84 | body { | ||
| 85 | background-color:#EFEFEF; | ||
| 86 | font: .9em "Lucida Sans Unicode", "Lucida Grande", sans-serif; | ||
| 87 | } | ||
| 88 | |||
| 89 | #wrapper{ | ||
| 90 | width:600px; | ||
| 91 | margin:40px auto 0; | ||
| 92 | text-align:center; | ||
| 93 | -moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3); | ||
| 94 | -webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3); | ||
| 95 | box-shadow: 5px 5px 10px rgba(0,0,0,0.3); | ||
| 96 | } | ||
| 97 | |||
| 98 | #wrapper h1{ | ||
| 99 | color:#FFF; | ||
| 100 | text-align:center; | ||
| 101 | margin-bottom:20px; | ||
| 102 | } | ||
| 103 | |||
| 104 | #wrapper a{ | ||
| 105 | display:block; | ||
| 106 | font-size:.9em; | ||
| 107 | padding-top:20px; | ||
| 108 | color:#FFF; | ||
| 109 | text-decoration:none; | ||
| 110 | text-align:center; | ||
| 111 | } | ||
| 112 | |||
| 113 | #container { | ||
| 114 | width:600px; | ||
| 115 | padding-bottom:15px; | ||
| 116 | background-color:#FFFFFF; | ||
| 117 | } | ||
| 118 | |||
| 119 | .navtop{ | ||
| 120 | height:40px; | ||
| 121 | background-color:#24B2EB; | ||
| 122 | padding:13px; | ||
| 123 | } | ||
| 124 | |||
| 125 | .content { | ||
| 126 | padding:10px 10px 25px; | ||
| 127 | background: #FFFFFF; | ||
| 128 | margin:; | ||
| 129 | color:#333; | ||
| 130 | } | ||
| 131 | |||
| 132 | a.button{ | ||
| 133 | color:white; | ||
| 134 | padding:15px 20px; | ||
| 135 | text-shadow:1px 1px 0 #00A5FF; | ||
| 136 | font-weight:bold; | ||
| 137 | text-align:center; | ||
| 138 | border:1px solid #24B2EB; | ||
| 139 | margin:0px 200px; | ||
| 140 | clear:both; | ||
| 141 | background-color: #24B2EB; | ||
| 142 | border-radius:100px; | ||
| 143 | -moz-border-radius:100px; | ||
| 144 | -webkit-border-radius:100px; | ||
| 145 | } | ||
| 146 | |||
| 147 | a.button:hover{ | ||
| 148 | text-decoration:none; | ||
| 149 | background-color: #24B2EB; | ||
| 150 | } | ||
| 151 | |||
| 152 | </style> | ||
| 153 | </head> | ||
| 154 | <body> | ||
| 155 | <div id="wrapper"> | ||
| 156 | <div id="container"> | ||
| 157 | <div class="navtop"> | ||
| 158 | <h1>{{.Title}}</h1> | ||
| 159 | </div> | ||
| 160 | <div id="content"> | ||
| 161 | {{.Content}} | ||
| 162 | <a href="/" title="Home" class="button">Go Home</a><br /> | ||
| 163 | |||
| 164 | <br>power by beego {{.BeegoVersion}} | ||
| 165 | </div> | ||
| 166 | </div> | ||
| 167 | </div> | ||
| 168 | </body> | ||
| 169 | </html> | ||
| 170 | ` | ||
| 171 | |||
| 172 | var ErrorMaps map[string]http.HandlerFunc | ||
| 173 | |||
| 174 | func init() { | ||
| 175 | ErrorMaps = make(map[string]http.HandlerFunc) | ||
| 176 | } | ||
| 177 | |||
| 178 | //404 | ||
| 179 | func NotFound(rw http.ResponseWriter, r *http.Request) { | ||
| 180 | t, _ := template.New("beegoerrortemp").Parse(errtpl) | ||
| 181 | data := make(map[string]interface{}) | ||
| 182 | data["Title"] = "Page Not Found" | ||
| 183 | data["Content"] = template.HTML("<br>The Page You have requested flown the coop." + | ||
| 184 | "<br>Perhaps you are here because:" + | ||
| 185 | "<br><br><ul>" + | ||
| 186 | "<br>The page has moved" + | ||
| 187 | "<br>The page no longer exists" + | ||
| 188 | "<br>You were looking for your puppy and got lost" + | ||
| 189 | "<br>You like 404 pages" + | ||
| 190 | "</ul>") | ||
| 191 | data["BeegoVersion"] = VERSION | ||
| 192 | t.Execute(rw, data) | ||
| 193 | } | ||
| 194 | |||
| 195 | //401 | ||
| 196 | func Unauthorized(rw http.ResponseWriter, r *http.Request) { | ||
| 197 | t, _ := template.New("beegoerrortemp").Parse(errtpl) | ||
| 198 | data := make(map[string]interface{}) | ||
| 199 | data["Title"] = "Unauthorized" | ||
| 200 | data["Content"] = template.HTML("<br>The Page You have requested can't authorized." + | ||
| 201 | "<br>Perhaps you are here because:" + | ||
| 202 | "<br><br><ul>" + | ||
| 203 | "<br>Check the credentials that you supplied" + | ||
| 204 | "<br>Check the address for errors" + | ||
| 205 | "</ul>") | ||
| 206 | data["BeegoVersion"] = VERSION | ||
| 207 | t.Execute(rw, data) | ||
| 208 | } | ||
| 209 | |||
| 210 | //403 | ||
| 211 | func Forbidden(rw http.ResponseWriter, r *http.Request) { | ||
| 212 | t, _ := template.New("beegoerrortemp").Parse(errtpl) | ||
| 213 | data := make(map[string]interface{}) | ||
| 214 | data["Title"] = "Forbidden" | ||
| 215 | data["Content"] = template.HTML("<br>The Page You have requested forbidden." + | ||
| 216 | "<br>Perhaps you are here because:" + | ||
| 217 | "<br><br><ul>" + | ||
| 218 | "<br>Your address may be blocked" + | ||
| 219 | "<br>The site may be disabled" + | ||
| 220 | "<br>You need to log in" + | ||
| 221 | "</ul>") | ||
| 222 | data["BeegoVersion"] = VERSION | ||
| 223 | t.Execute(rw, data) | ||
| 224 | } | ||
| 225 | |||
| 226 | //503 | ||
| 227 | func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) { | ||
| 228 | t, _ := template.New("beegoerrortemp").Parse(errtpl) | ||
| 229 | data := make(map[string]interface{}) | ||
| 230 | data["Title"] = "Service Unavailable" | ||
| 231 | data["Content"] = template.HTML("<br>The Page You have requested unavailable." + | ||
| 232 | "<br>Perhaps you are here because:" + | ||
| 233 | "<br><br><ul>" + | ||
| 234 | "<br><br>The page is overloaded" + | ||
| 235 | "<br>Please try again later." + | ||
| 236 | "</ul>") | ||
| 237 | data["BeegoVersion"] = VERSION | ||
| 238 | t.Execute(rw, data) | ||
| 239 | } | ||
| 240 | |||
| 241 | //500 | ||
| 242 | func InternalServerError(rw http.ResponseWriter, r *http.Request) { | ||
| 243 | t, _ := template.New("beegoerrortemp").Parse(errtpl) | ||
| 244 | data := make(map[string]interface{}) | ||
| 245 | data["Title"] = "Internal Server Error" | ||
| 246 | data["Content"] = template.HTML("<br>The Page You have requested has down now." + | ||
| 247 | "<br><br><ul>" + | ||
| 248 | "<br>simply try again later" + | ||
| 249 | "<br>you should report the fault to the website administrator" + | ||
| 250 | "</ul>") | ||
| 251 | data["BeegoVersion"] = VERSION | ||
| 252 | t.Execute(rw, data) | ||
| 253 | } | ||
| 254 | |||
| 255 | func registerErrorHander() { | ||
| 256 | if _, ok := ErrorMaps["404"]; !ok { | ||
| 257 | ErrorMaps["404"] = NotFound | ||
| 258 | } | ||
| 259 | |||
| 260 | if _, ok := ErrorMaps["401"]; !ok { | ||
| 261 | ErrorMaps["401"] = Unauthorized | ||
| 262 | } | ||
| 263 | |||
| 264 | if _, ok := ErrorMaps["403"]; !ok { | ||
| 265 | ErrorMaps["403"] = Forbidden | ||
| 266 | } | ||
| 267 | |||
| 268 | if _, ok := ErrorMaps["503"]; !ok { | ||
| 269 | ErrorMaps["503"] = ServiceUnavailable | ||
| 270 | } | ||
| 271 | |||
| 272 | if _, ok := ErrorMaps["500"]; !ok { | ||
| 273 | ErrorMaps["500"] = InternalServerError | ||
| 274 | } | ||
| 275 | } | ... | ... |
| ... | @@ -187,6 +187,10 @@ func (p *ControllerRegistor) FilterPrefixPath(path string, filter http.HandlerFu | ... | @@ -187,6 +187,10 @@ func (p *ControllerRegistor) FilterPrefixPath(path string, filter http.HandlerFu |
| 187 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { | 187 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { |
| 188 | defer func() { | 188 | defer func() { |
| 189 | if err := recover(); err != nil { | 189 | if err := recover(); err != nil { |
| 190 | errstr := fmt.Sprint(err) | ||
| 191 | if handler, ok := ErrorMaps[errstr]; ok { | ||
| 192 | handler(rw, r) | ||
| 193 | } else { | ||
| 190 | if !RecoverPanic { | 194 | if !RecoverPanic { |
| 191 | // go back to panic | 195 | // go back to panic |
| 192 | panic(err) | 196 | panic(err) |
| ... | @@ -208,6 +212,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -208,6 +212,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 208 | } | 212 | } |
| 209 | } | 213 | } |
| 210 | } | 214 | } |
| 215 | } | ||
| 211 | }() | 216 | }() |
| 212 | w := &responseWriter{writer: rw} | 217 | w := &responseWriter{writer: rw} |
| 213 | 218 | ||
| ... | @@ -385,8 +390,12 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -385,8 +390,12 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 385 | 390 | ||
| 386 | //if no matches to url, throw a not found exception | 391 | //if no matches to url, throw a not found exception |
| 387 | if w.started == false { | 392 | if w.started == false { |
| 393 | if h, ok := ErrorMaps["404"]; ok { | ||
| 394 | h(w, r) | ||
| 395 | } else { | ||
| 388 | http.NotFound(w, r) | 396 | http.NotFound(w, r) |
| 389 | } | 397 | } |
| 398 | } | ||
| 390 | } | 399 | } |
| 391 | 400 | ||
| 392 | //responseWriter is a wrapper for the http.ResponseWriter | 401 | //responseWriter is a wrapper for the http.ResponseWriter | ... | ... |
-
Please register or sign in to post a comment