worker/client: expose server errors
The worker API returns errors of the form:
{ "message": "..." }
Print the message of those errors when receiving an error on the client.
This adds an `Error` type to openapi.yml and marks all routes as
returning it on 4XX and 5XX.
This commit is contained in:
parent
3bedd25087
commit
ca35f25fcf
4 changed files with 80 additions and 13 deletions
|
|
@ -10,6 +10,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Error defines model for Error.
|
||||||
|
type Error struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
// RequestJobJSONBody defines parameters for RequestJob.
|
// RequestJobJSONBody defines parameters for RequestJob.
|
||||||
type RequestJobJSONBody map[string]interface{}
|
type RequestJobJSONBody map[string]interface{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,17 @@ paths:
|
||||||
- OK
|
- OK
|
||||||
required:
|
required:
|
||||||
- status
|
- status
|
||||||
|
4XX:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
5XX:
|
||||||
|
description: ''
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
operationId: GetStatus
|
operationId: GetStatus
|
||||||
description: Simple status handler to check whether the service is up.
|
description: Simple status handler to check whether the service is up.
|
||||||
/jobs:
|
/jobs:
|
||||||
|
|
@ -53,6 +64,17 @@ paths:
|
||||||
- manifest
|
- manifest
|
||||||
- location
|
- location
|
||||||
- id
|
- id
|
||||||
|
4XX:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
5XX:
|
||||||
|
description: ''
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
operationId: RequestJob
|
operationId: RequestJob
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
|
|
@ -85,6 +107,18 @@ paths:
|
||||||
type: boolean
|
type: boolean
|
||||||
required:
|
required:
|
||||||
- canceled
|
- canceled
|
||||||
|
4XX:
|
||||||
|
description: ''
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
5XX:
|
||||||
|
description: ''
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
operationId: GetJob
|
operationId: GetJob
|
||||||
description: ''
|
description: ''
|
||||||
patch:
|
patch:
|
||||||
|
|
@ -127,6 +161,17 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
4XX:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
5XX:
|
||||||
|
description: ''
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
operationId: UploadJobArtifact
|
operationId: UploadJobArtifact
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
|
|
@ -134,4 +179,12 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
components:
|
components:
|
||||||
schemas: {}
|
schemas:
|
||||||
|
Error:
|
||||||
|
title: Error
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- message
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
@ -94,9 +93,7 @@ func (c *Client) RequestJob() (Job, error) {
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
if response.StatusCode != http.StatusCreated {
|
if response.StatusCode != http.StatusCreated {
|
||||||
var er errorResponse
|
return nil, errorFromResponse(response, "error requesting job")
|
||||||
_ = json.NewDecoder(response.Body).Decode(&er)
|
|
||||||
return nil, fmt.Errorf("couldn't create job, got %d: %s", response.StatusCode, er.Message)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var jr requestJobResponse
|
var jr requestJobResponse
|
||||||
|
|
@ -157,7 +154,7 @@ func (j *job) Update(status common.ImageBuildState, result *osbuild.Result) erro
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
if response.StatusCode != http.StatusOK {
|
if response.StatusCode != http.StatusOK {
|
||||||
return errors.New("error setting job status")
|
return errorFromResponse(response, "error setting job status")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -171,7 +168,7 @@ func (j *job) Canceled() (bool, error) {
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
if response.StatusCode != http.StatusOK {
|
if response.StatusCode != http.StatusOK {
|
||||||
return false, fmt.Errorf("unexpected return value: %v", response.StatusCode)
|
return false, errorFromResponse(response, "error fetching job info")
|
||||||
}
|
}
|
||||||
|
|
||||||
var jr getJobResponse
|
var jr getJobResponse
|
||||||
|
|
@ -205,10 +202,26 @@ func (j *job) UploadArtifact(name string, reader io.Reader) error {
|
||||||
|
|
||||||
req.Header.Add("Content-Type", "application/octet-stream")
|
req.Header.Add("Content-Type", "application/octet-stream")
|
||||||
|
|
||||||
_, err = j.requester.Do(req)
|
response, err := j.requester.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error uploading artifcat: %v", err)
|
return fmt.Errorf("error uploading artifact: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return errorFromResponse(response, "error uploading artifact")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parses an api.Error from a response and returns it as a golang error. Other
|
||||||
|
// errors, such failing to parse the response, are returned as golang error as
|
||||||
|
// well. If client code expects an error, it gets one.
|
||||||
|
func errorFromResponse(response *http.Response, message string) error {
|
||||||
|
var e api.Error
|
||||||
|
err := json.NewDecoder(response.Body).Decode(&e)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse error response: %v", err)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%v: %v — %v", message, response.StatusCode, e.Message)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,6 @@ type statusResponse struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type errorResponse struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestJobResponse struct {
|
type requestJobResponse struct {
|
||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
Manifest distro.Manifest `json:"manifest"`
|
Manifest distro.Manifest `json:"manifest"`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue