Skip to content

Commit

Permalink
Clean up API error messages (hashicorp-forge#203)
Browse files Browse the repository at this point in the history
* Standardize on plain text HTTP error messages for now

* Correctly surface HTTP error messages
  • Loading branch information
jfreda committed Jun 6, 2023
1 parent eac44ec commit 928acc5
Show file tree
Hide file tree
Showing 11 changed files with 22 additions and 37 deletions.
6 changes: 3 additions & 3 deletions internal/api/approvals.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,19 +289,19 @@ func ApprovalHandler(
userEmail := r.Context().Value("userEmail").(string)
if docObj.GetStatus() != "In-Review" && docObj.GetStatus() != "In Review" {
http.Error(w,
`{"error": "Only documents in the "In-Review" status can be approved"}`,
"Only documents in the \"In-Review\" status can be approved",
http.StatusBadRequest)
return
}
if !contains(docObj.GetApprovers(), userEmail) {
http.Error(w,
`{"error": "Not authorized as a document approver"}`,
"Not authorized as a document approver",
http.StatusUnauthorized)
return
}
if contains(docObj.GetApprovedBy(), userEmail) {
http.Error(w,
`{"error": "Document already approved by user"}`,
"Document already approved by user",
http.StatusBadRequest)
return
}
Expand Down
4 changes: 1 addition & 3 deletions internal/api/documents.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ func DocumentHandler(
// Authorize request (only the owner can PATCH the doc).
userEmail := r.Context().Value("userEmail").(string)
if docObj.GetOwners()[0] != userEmail {
http.Error(w,
`{"error": "Not a document owner"}`,
http.StatusUnauthorized)
http.Error(w, "Not a document owner", http.StatusUnauthorized)
return
}

Expand Down
7 changes: 3 additions & 4 deletions internal/api/drafts.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ func DraftsHandler(
"path", r.URL.Path,
"error", err,
)
errJSON := fmt.Sprintf(`{"error": "%s"}`, userErrMsg)
http.Error(w, errJSON, httpCode)
http.Error(w, userErrMsg, httpCode)
}

// Authorize request.
Expand Down Expand Up @@ -515,7 +514,7 @@ func DraftsDocumentHandler(
}
if !isOwner && !isContributor {
http.Error(w,
`{"error": "Only owners or contributors can access a draft document"}`,
"Only owners or contributors can access a draft document",
http.StatusUnauthorized)
return
}
Expand Down Expand Up @@ -613,7 +612,7 @@ func DraftsDocumentHandler(
// Authorize request.
if !isOwner {
http.Error(w,
`{"error": "Only owners can delete a draft document"}`,
"Only owners can delete a draft document",
http.StatusUnauthorized)
return
}
Expand Down
3 changes: 1 addition & 2 deletions internal/api/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,5 @@ func respondError(
"path", r.URL.Path,
}, extraArgs...)...,
)
errJSON := fmt.Sprintf(`{"error": "%s"}`, userErrMsg)
http.Error(w, errJSON, httpCode)
http.Error(w, userErrMsg, httpCode)
}
6 changes: 2 additions & 4 deletions internal/api/me.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ func MeHandler(
"path", r.URL.Path,
"error", err,
)
errJSON := fmt.Sprintf(`{"error": "%s"}`, userErrMsg)
http.Error(w, errJSON, httpCode)
http.Error(w, userErrMsg, httpCode)
}

// Authorize request.
Expand Down Expand Up @@ -67,8 +66,7 @@ func MeHandler(
"path", r.URL.Path,
"error", err,
)
errJSON := fmt.Sprintf(`{"error": "%s"}`, userErrMsg)
http.Error(w, errJSON, httpCode)
http.Error(w, userErrMsg, httpCode)
}

ppl, err := s.SearchPeople(userEmail, "emailAddresses,names,photos")
Expand Down
4 changes: 1 addition & 3 deletions internal/api/me_subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"encoding/json"
"fmt"
"net/http"

"github.com/hashicorp-forge/hermes/internal/config"
Expand Down Expand Up @@ -30,8 +29,7 @@ func MeSubscriptionsHandler(
"path", r.URL.Path,
"error", err,
)
errJSON := fmt.Sprintf(`{"error": "%s"}`, userErrMsg)
http.Error(w, errJSON, httpCode)
http.Error(w, userErrMsg, httpCode)
}

// Authorize request.
Expand Down
10 changes: 4 additions & 6 deletions internal/api/reviews.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ func ReviewHandler(
"method", r.Method,
"doc_id", docID,
)
http.Error(w, `{"error": "Error creating review"}`,
http.StatusInternalServerError)
http.Error(w, "Error creating review", http.StatusInternalServerError)
return
}

Expand All @@ -202,8 +201,7 @@ func ReviewHandler(
"method", r.Method,
"doc_id", docID,
)
http.Error(w, `{"error": "Error creating review"}`,
http.StatusInternalServerError)
http.Error(w, "Error creating review", http.StatusInternalServerError)
return
}
docObj.SetModifiedTime(modifiedTime.Unix())
Expand Down Expand Up @@ -515,7 +513,7 @@ func ReviewHandler(
"method", r.Method,
"path", r.URL.Path,
)
http.Error(w, `{"error": "Error sending subscriber email"}`,
http.Error(w, "Error sending subscriber email",
http.StatusInternalServerError)
return
}
Expand Down Expand Up @@ -545,7 +543,7 @@ func ReviewHandler(
"method", r.Method,
"path", r.URL.Path,
)
http.Error(w, `{"error": "Error sending subscriber email"}`,
http.Error(w, "Error sending subscriber email",
http.StatusInternalServerError)
return
}
Expand Down
6 changes: 2 additions & 4 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ func AuthenticateRequest(
if err != nil {
log.Error("error creating Okta authenticator")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w,
`{"error": "Internal server error"}`, http.StatusInternalServerError)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
})
}
Expand Down Expand Up @@ -55,8 +54,7 @@ func validateUserEmail(
log.Error("userEmail is not set in the request context",
"method", r.Method,
"path", r.URL.Path)
http.Error(w,
`{"error": "Internal server error"}`, http.StatusInternalServerError)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
}
6 changes: 2 additions & 4 deletions internal/auth/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,15 @@ func AuthenticateRequest(
"method", r.Method,
"path", r.URL.Path,
)
http.Error(w,
`{"error": "Unauthorized"}`, http.StatusUnauthorized)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
if ti.Email == "" {
log.Error("no user email found in Google access token",
"method", r.Method,
"path", r.URL.Path,
)
http.Error(w,
`{"error": "Unauthorized"}`, http.StatusUnauthorized)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}

Expand Down
2 changes: 1 addition & 1 deletion internal/auth/oktaalb/oktaalb.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (oa *OktaAuthorizer) EnforceOktaAuth(next http.Handler) http.Handler {
"method", r.Method,
"path", r.URL.Path,
)
http.Error(w, `{"error": "Unauthorized"}`, http.StatusUnauthorized)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
} else {
// Set user email from the OIDC claims.
Expand Down
5 changes: 2 additions & 3 deletions web/app/services/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ export default class FetchService extends Service {
// handle poll-call failures via the session service
return;
}
// log the response so it's easier to debug environment-specific errors
console.error("fetch error:", resp);
throw new Error(`Bad response: ${resp.statusText}`);
const errText = await resp.text();
throw new Error(`Bad response: ${errText}`);
}

return resp;
Expand Down

0 comments on commit 928acc5

Please sign in to comment.