PageRenderTime 38ms CodeModel.GetById 25ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/middleware/error.go

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