Chromium Code Reviews| 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 |