Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Handle wac template errors
  • Loading branch information
Emyrk committed Mar 9, 2021
commit 17a3f56d950a54ba289e5af24f38093cb45e9b6b
27 changes: 23 additions & 4 deletions coder-sdk/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,43 @@ type apiError struct {

// apiErrorMsg contains the rich error information returned by API errors.
type apiErrorMsg struct {
Msg string `json:"msg"`
Msg string `json:"msg"`
Code string `json:"code"`
Details json.RawMessage `json:"details"`
}

// HTTPError represents an error from the Coder API.
type HTTPError struct {
*http.Response
cached *apiError
cachedErr error
}

func (e *HTTPError) Error() string {
func (e *HTTPError) Payload() (*apiError, error) {
var msg apiError
if e.cached != nil || e.cachedErr != nil {
return e.cached, e.cachedErr
}

// Try to decode the payload as an error, if it fails or if there is no error message,
// return the response URL with the status.
if err := json.NewDecoder(e.Response.Body).Decode(&msg); err != nil || msg.Err.Msg == "" {
if err := json.NewDecoder(e.Response.Body).Decode(&msg); err != nil {
e.cachedErr = err
return nil, err
}

e.cached = &msg
return &msg, nil
}

func (e *HTTPError) Error() string {
apiErr, err := e.Payload()
if err != nil || apiErr.Err.Msg == "" {
return fmt.Sprintf("%s: %d %s", e.Request.URL, e.StatusCode, e.Status)
}

// If the payload was a in the expected error format with a message, include it.
return msg.Err.Msg
return apiErr.Err.Msg
}

func bodyError(resp *http.Response) error {
Expand Down
35 changes: 32 additions & 3 deletions internal/cmd/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ func createEnvFromRepoCmd() *cobra.Command {
Long: "Create a new Coder environment from a config file.",
Hidden: true,
Example: `# create a new environment from git repository template
coder envs create-from-repo --repo-url github.com/cdr/m --branch my-branch
coder envs create-from-repo -f coder.yaml`,
coder envs create-from-config --repo-url github.com/cdr/m --branch my-branch
coder envs create-from-config -f coder.yaml`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

Expand Down Expand Up @@ -355,7 +355,7 @@ coder envs create-from-repo -f coder.yaml`,

tpl, err := client.ParseTemplate(ctx, req)
if err != nil {
return xerrors.Errorf("parse environment template config: %w", err)
return handleTemplateError(err)
}

provider, err := coderutil.DefaultWorkspaceProvider(ctx, client)
Expand Down Expand Up @@ -397,6 +397,35 @@ coder envs create-from-repo -f coder.yaml`,
return cmd
}

func handleTemplateError(origError error) error {
var httpError *coder.HTTPError
if !xerrors.As(origError, &httpError) {
return origError
}

ae, err := httpError.Payload()
if err != nil {
return origError
}

switch ae.Err.Code {
case "wac_template":
type payload struct {
ErrorType string `json:"error_type"`
Msgs []string `json:"messages"`
}

var p payload
err := json.Unmarshal(ae.Err.Details, &p)
if err != nil {
return origError
}

return clog.Error(p.ErrorType, p.Msgs...)
}
return origError
}

func editEnvCmd() *cobra.Command {
var (
org string
Expand Down