OLD | NEW |
---|---|
1 // Copyright 2015 The LUCI Authors. | 1 // Copyright 2015 The LUCI Authors. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 package common | 15 package common |
16 | 16 |
17 import ( | 17 import ( |
18 » "github.com/luci/luci-go/server/router" | 18 » "net/http" |
19 » "github.com/luci/luci-go/server/templates" | 19 |
20 » "github.com/luci/luci-go/common/errors" | |
20 ) | 21 ) |
21 | 22 |
22 // ErrorPage writes an error page into c.Writer with an http code "code" | 23 // ErrorCode represents milo's internal error code system. The subsystems in |
23 // and custom message. | 24 // milo can attach an ErrorCode to an error (using ErrorTag), and then the |
24 func ErrorPage(c *router.Context, code int, message string) { | 25 // html frontends know how to render the error in a way that will help the user. |
Ryan Tseng
2017/07/13 22:00:46
html and grpc
iannucci
2017/07/14 19:00:23
Done.
| |
25 » c.Writer.WriteHeader(code) | 26 type ErrorCode int |
26 » templates.MustRender(c.Context, c.Writer, "pages/error.html", templates. Args{ | 27 |
27 » » "Code": code, | 28 const ( |
28 » » "Message": message, | 29 » // CodeUnknown means an error happened, but we weren't able to classify it. |
29 » }) | 30 » CodeUnknown ErrorCode = iota |
31 | |
32 » // CodeUnauthorized occurs when the user may be able to see build, but t hey're | |
Ryan Tseng
2017/07/13 22:00:47
but they weren't logged in...
iannucci
2017/07/14 19:00:23
Done.
| |
33 » // not logged in, so we don't know. | |
34 » CodeUnauthorized | |
35 | |
36 » // CodeNoAccess occurs when the user is not able to see the build given the | |
Ryan Tseng
2017/07/13 22:00:47
was not able to see... (I noticed the convention h
iannucci
2017/07/14 19:00:23
tweaked
| |
37 » // account that they're logged in as. | |
38 » CodeNoAccess | |
39 | |
40 » // CodeNotFound occurs when we weren't able to find the build that the | |
41 » // user asked for. | |
42 » CodeNotFound | |
43 | |
44 » // CodeParameterError occurs when one or more of the user-provided param eters | |
45 » // was malformed. | |
46 » CodeParameterError | |
47 ) | |
48 | |
49 var httpCode = map[ErrorCode]int{ | |
50 » CodeUnauthorized: http.StatusUnauthorized, | |
51 » CodeNoAccess: http.StatusForbidden, | |
52 » CodeNotFound: http.StatusNotFound, | |
53 » CodeParameterError: http.StatusBadRequest, | |
30 } | 54 } |
55 | |
56 // HTTPStatus returns an HTTP Status code corresponding to this ErrorCode. | |
57 func (c ErrorCode) HTTPStatus() int { | |
58 if ret, ok := httpCode[c]; ok { | |
59 return ret | |
60 } | |
61 return http.StatusInternalServerError | |
62 } | |
63 | |
64 // Tag returns an errors.TagValue for this code. | |
65 func (c ErrorCode) Tag() errors.TagValue { | |
66 return ErrorTag.With(c) | |
67 } | |
68 | |
69 // GenerateErrorTagValue implements errors.TagValueGenerator so that ErrorCodes | |
70 // can be used like: | |
71 // errors.Annotate(err).Tag(CodeNotFound) | |
72 // errors.New("terrible thing", CodeNotFound) | |
73 func (c ErrorCode) GenerateErrorTagValue() errors.TagValue { | |
74 return ErrorTag.With(c) | |
75 } | |
76 | |
77 type errorTag struct{ Key errors.TagKey } | |
78 | |
79 func (t *errorTag) In(err error) ErrorCode { | |
80 v, ok := errors.TagValueIn(t.Key, err) | |
81 if ok { | |
82 return v.(ErrorCode) | |
83 } | |
84 return CodeUnknown | |
85 } | |
86 | |
87 func (t *errorTag) With(value ErrorCode) errors.TagValue { | |
88 return errors.TagValue{Key: t.Key, Value: value} | |
89 } | |
90 | |
91 // ErrorTag should be used to tag errors in the milo ecosystem to categorize | |
92 // them so they can be rendered properly in the frontend. | |
93 var ErrorTag = errorTag{errors.NewTagKey("holds a milo ErrorCode")} | |
OLD | NEW |