PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/middleware/error.go

https://github.com/redaready/beego
Go | 330 lines | 288 code | 20 blank | 22 comment | 13 complexity | f87107d61be3ebde4b8297a688552487 MD5 | raw file
Possible License(s): Apache-2.0
  1. // Beego (http://beego.me/)
  2. // @description beego is an open-source, high-performance web framework for the Go programming language.
  3. // @link http://github.com/astaxie/beego for the canonical source repository
  4. // @license http://github.com/astaxie/beego/blob/master/LICENSE
  5. // @authors astaxie
  6. package middleware
  7. import (
  8. "fmt"
  9. "html/template"
  10. "net/http"
  11. "runtime"
  12. "strconv"
  13. )
  14. var (
  15. AppName string
  16. VERSION string
  17. )
  18. var tpl = `
  19. <!DOCTYPE html>
  20. <html>
  21. <head>
  22. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  23. <title>beego application error</title>
  24. <style>
  25. html, body, body * {padding: 0; margin: 0;}
  26. #header {background:#ffd; border-bottom:solid 2px #A31515; padding: 20px 10px;}
  27. #header h2{ }
  28. #footer {border-top:solid 1px #aaa; padding: 5px 10px; font-size: 12px; color:green;}
  29. #content {padding: 5px;}
  30. #content .stack b{ font-size: 13px; color: red;}
  31. #content .stack pre{padding-left: 10px;}
  32. table {}
  33. td.t {text-align: right; padding-right: 5px; color: #888;}
  34. </style>
  35. <script type="text/javascript">
  36. </script>
  37. </head>
  38. <body>
  39. <div id="header">
  40. <h2>{{.AppError}}</h2>
  41. </div>
  42. <div id="content">
  43. <table>
  44. <tr>
  45. <td class="t">Request Method: </td><td>{{.RequestMethod}}</td>
  46. </tr>
  47. <tr>
  48. <td class="t">Request URL: </td><td>{{.RequestURL}}</td>
  49. </tr>
  50. <tr>
  51. <td class="t">RemoteAddr: </td><td>{{.RemoteAddr }}</td>
  52. </tr>
  53. </table>
  54. <div class="stack">
  55. <b>Stack</b>
  56. <pre>{{.Stack}}</pre>
  57. </div>
  58. </div>
  59. <div id="footer">
  60. <p>beego {{ .BeegoVersion }} (beego framework)</p>
  61. <p>golang version: {{.GoVersion}}</p>
  62. </div>
  63. </body>
  64. </html>
  65. `
  66. // render default application error page with error and stack string.
  67. func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) {
  68. t, _ := template.New("beegoerrortemp").Parse(tpl)
  69. data := make(map[string]string)
  70. data["AppError"] = AppName + ":" + fmt.Sprint(err)
  71. data["RequestMethod"] = r.Method
  72. data["RequestURL"] = r.RequestURI
  73. data["RemoteAddr"] = r.RemoteAddr
  74. data["Stack"] = Stack
  75. data["BeegoVersion"] = VERSION
  76. data["GoVersion"] = runtime.Version()
  77. rw.WriteHeader(500)
  78. t.Execute(rw, data)
  79. }
  80. var errtpl = `
  81. <!DOCTYPE html>
  82. <html lang="en">
  83. <head>
  84. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  85. <title>{{.Title}}</title>
  86. <style type="text/css">
  87. * {
  88. margin:0;
  89. padding:0;
  90. }
  91. body {
  92. background-color:#EFEFEF;
  93. font: .9em "Lucida Sans Unicode", "Lucida Grande", sans-serif;
  94. }
  95. #wrapper{
  96. width:600px;
  97. margin:40px auto 0;
  98. text-align:center;
  99. -moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
  100. -webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
  101. box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
  102. }
  103. #wrapper h1{
  104. color:#FFF;
  105. text-align:center;
  106. margin-bottom:20px;
  107. }
  108. #wrapper a{
  109. display:block;
  110. font-size:.9em;
  111. padding-top:20px;
  112. color:#FFF;
  113. text-decoration:none;
  114. text-align:center;
  115. }
  116. #container {
  117. width:600px;
  118. padding-bottom:15px;
  119. background-color:#FFFFFF;
  120. }
  121. .navtop{
  122. height:40px;
  123. background-color:#24B2EB;
  124. padding:13px;
  125. }
  126. .content {
  127. padding:10px 10px 25px;
  128. background: #FFFFFF;
  129. margin:;
  130. color:#333;
  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. a.button:hover{
  147. text-decoration:none;
  148. background-color: #24B2EB;
  149. }
  150. </style>
  151. </head>
  152. <body>
  153. <div id="wrapper">
  154. <div id="container">
  155. <div class="navtop">
  156. <h1>{{.Title}}</h1>
  157. </div>
  158. <div id="content">
  159. {{.Content}}
  160. <a href="/" title="Home" class="button">Go Home</a><br />
  161. <br>Powered by beego {{.BeegoVersion}}
  162. </div>
  163. </div>
  164. </div>
  165. </body>
  166. </html>
  167. `
  168. // map of http handlers for each error string.
  169. var ErrorMaps map[string]http.HandlerFunc
  170. func init() {
  171. ErrorMaps = make(map[string]http.HandlerFunc)
  172. }
  173. // show 404 notfound error.
  174. func NotFound(rw http.ResponseWriter, r *http.Request) {
  175. t, _ := template.New("beegoerrortemp").Parse(errtpl)
  176. data := make(map[string]interface{})
  177. data["Title"] = "Page Not Found"
  178. data["Content"] = template.HTML("<br>The page you have requested has flown the coop." +
  179. "<br>Perhaps you are here because:" +
  180. "<br><br><ul>" +
  181. "<br>The page has moved" +
  182. "<br>The page no longer exists" +
  183. "<br>You were looking for your puppy and got lost" +
  184. "<br>You like 404 pages" +
  185. "</ul>")
  186. data["BeegoVersion"] = VERSION
  187. //rw.WriteHeader(http.StatusNotFound)
  188. t.Execute(rw, data)
  189. }
  190. // show 401 unauthorized error.
  191. func Unauthorized(rw http.ResponseWriter, r *http.Request) {
  192. t, _ := template.New("beegoerrortemp").Parse(errtpl)
  193. data := make(map[string]interface{})
  194. data["Title"] = "Unauthorized"
  195. data["Content"] = template.HTML("<br>The page you have requested can't be authorized." +
  196. "<br>Perhaps you are here because:" +
  197. "<br><br><ul>" +
  198. "<br>The credentials you supplied are incorrect" +
  199. "<br>There are errors in the website address" +
  200. "</ul>")
  201. data["BeegoVersion"] = VERSION
  202. //rw.WriteHeader(http.StatusUnauthorized)
  203. t.Execute(rw, data)
  204. }
  205. // show 403 forbidden error.
  206. func Forbidden(rw http.ResponseWriter, r *http.Request) {
  207. t, _ := template.New("beegoerrortemp").Parse(errtpl)
  208. data := make(map[string]interface{})
  209. data["Title"] = "Forbidden"
  210. data["Content"] = template.HTML("<br>The page you have requested is forbidden." +
  211. "<br>Perhaps you are here because:" +
  212. "<br><br><ul>" +
  213. "<br>Your address may be blocked" +
  214. "<br>The site may be disabled" +
  215. "<br>You need to log in" +
  216. "</ul>")
  217. data["BeegoVersion"] = VERSION
  218. //rw.WriteHeader(http.StatusForbidden)
  219. t.Execute(rw, data)
  220. }
  221. // show 503 service unavailable error.
  222. func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) {
  223. t, _ := template.New("beegoerrortemp").Parse(errtpl)
  224. data := make(map[string]interface{})
  225. data["Title"] = "Service Unavailable"
  226. data["Content"] = template.HTML("<br>The page you have requested is unavailable." +
  227. "<br>Perhaps you are here because:" +
  228. "<br><br><ul>" +
  229. "<br><br>The page is overloaded" +
  230. "<br>Please try again later." +
  231. "</ul>")
  232. data["BeegoVersion"] = VERSION
  233. //rw.WriteHeader(http.StatusServiceUnavailable)
  234. t.Execute(rw, data)
  235. }
  236. // show 500 internal server error.
  237. func InternalServerError(rw http.ResponseWriter, r *http.Request) {
  238. t, _ := template.New("beegoerrortemp").Parse(errtpl)
  239. data := make(map[string]interface{})
  240. data["Title"] = "Internal Server Error"
  241. data["Content"] = template.HTML("<br>The page you have requested is down right now." +
  242. "<br><br><ul>" +
  243. "<br>Please try again later and report the error to the website administrator" +
  244. "<br></ul>")
  245. data["BeegoVersion"] = VERSION
  246. //rw.WriteHeader(http.StatusInternalServerError)
  247. t.Execute(rw, data)
  248. }
  249. // show 500 internal error with simple text string.
  250. func SimpleServerError(rw http.ResponseWriter, r *http.Request) {
  251. http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
  252. }
  253. // add http handler for given error string.
  254. func Errorhandler(err string, h http.HandlerFunc) {
  255. ErrorMaps[err] = h
  256. }
  257. // register default error http handlers, 404,401,403,500 and 503.
  258. func RegisterErrorHandler() {
  259. if _, ok := ErrorMaps["404"]; !ok {
  260. ErrorMaps["404"] = NotFound
  261. }
  262. if _, ok := ErrorMaps["401"]; !ok {
  263. ErrorMaps["401"] = Unauthorized
  264. }
  265. if _, ok := ErrorMaps["403"]; !ok {
  266. ErrorMaps["403"] = Forbidden
  267. }
  268. if _, ok := ErrorMaps["503"]; !ok {
  269. ErrorMaps["503"] = ServiceUnavailable
  270. }
  271. if _, ok := ErrorMaps["500"]; !ok {
  272. ErrorMaps["500"] = InternalServerError
  273. }
  274. }
  275. // show error string as simple text message.
  276. // if error string is empty, show 500 error as default.
  277. func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg string) {
  278. if h, ok := ErrorMaps[errcode]; ok {
  279. isint, err := strconv.Atoi(errcode)
  280. if err != nil {
  281. isint = 500
  282. }
  283. w.WriteHeader(isint)
  284. h(w, r)
  285. return
  286. } else {
  287. isint, err := strconv.Atoi(errcode)
  288. if err != nil {
  289. isint = 500
  290. }
  291. if isint == 400 {
  292. msg = "404 page not found"
  293. }
  294. w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  295. w.WriteHeader(isint)
  296. fmt.Fprintln(w, msg)
  297. return
  298. }
  299. }