-
Notifications
You must be signed in to change notification settings - Fork 943
chore: More UI friendly errors #1994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
352b86a
7f9b66a
46b52d5
1592d08
6b08a08
1b3947f
deb5cf1
5e34b5f
f355dff
6566e83
fed7b7f
5c4ec92
e373a06
73ffa22
5d59312
a8e78bb
ee2f547
4a5d03a
8259e51
819f2e1
1116f94
102a01f
af169f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,8 +52,19 @@ func init() { | |
|
||
// Response represents a generic HTTP response. | ||
type Response struct { | ||
Message string `json:"message" validate:"required"` | ||
Errors []Error `json:"errors,omitempty" validate:"required"` | ||
// Message is for general user-friendly error messages. This message will | ||
// be shown at the top/bottom of a form, or in a toast on the UI. | ||
Message string `json:"message"` | ||
// Internal has the technical error information (err.Error()). These details | ||
// might come from external packages and might not be user friendly. | ||
// Do not populate this error field with any sensitive information or | ||
// any errors that may be a security implication. These details are still | ||
// available to more technical users. | ||
Internal string `json:"internal"` | ||
// Errors are form field-specific friendly error messages. They will be | ||
// shown on a form field in the UI. These can also be used to add additional | ||
// context if there is a set of errors in the primary 'Message'. | ||
Errors []Error `json:"errors,omitempty"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will be difficult to understand at a glance how I'd display an error to the user. Here's an alternative structure that just tweaks the names a bit and adds examples, but could help: type Response struct {
// An actionable message that depicts actions the request took. Examples:
// - "A user has been created."
// - "Failed to create a user."
Message string `json:"message"`
// A debug message that provides further insight into why the action failed.
// - "database: too many open connections"
// - "stat: too many open files"
Detail string `json:"detail"`
} I don't know what to name I'm curious for your take @presleyp, you're a magician with words! 🪄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Kira-Pilot suggested I like But I know @Emyrk doesn't want this PR to be open for long, maybe these tweaks can be a followup. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can change that now, that's easy with IDE tools |
||
} | ||
|
||
// Error represents a scoped error to a user input. | ||
|
@@ -64,7 +75,7 @@ type Error struct { | |
|
||
func Forbidden(rw http.ResponseWriter) { | ||
Write(rw, http.StatusForbidden, Response{ | ||
Message: "forbidden", | ||
Message: "Forbidden", | ||
}) | ||
} | ||
|
||
|
@@ -93,7 +104,8 @@ func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool { | |
err := json.NewDecoder(r.Body).Decode(value) | ||
if err != nil { | ||
Write(rw, http.StatusBadRequest, Response{ | ||
Message: fmt.Sprintf("read body: %s", err.Error()), | ||
Message: "Request body must be valid json", | ||
Emyrk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Internal: err.Error(), | ||
}) | ||
return false | ||
} | ||
|
@@ -115,7 +127,8 @@ func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool { | |
} | ||
if err != nil { | ||
Write(rw, http.StatusInternalServerError, Response{ | ||
Message: fmt.Sprintf("validation: %s", err.Error()), | ||
Message: "Internal error validating request body payload", | ||
Internal: err.Error(), | ||
}) | ||
return false | ||
} | ||
|
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: what allowed us to make this change? Does it mean that we no longer send those random
Message
errors on forbidden routes?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vapurrmaid for security reasons all forbidden messages should be identical. If they were different, then the different errors allow the end user to gain information.
There is a line of "security" vs "usability" that we will need to decide on these endpoints. As it's unhelpful by design.