diff --git a/error.go b/error.go index 3ffd833..beb1302 100644 --- a/error.go +++ b/error.go @@ -1,5 +1,7 @@ package ipp +import "fmt" + func IsNotExistsError(err error) bool { if err == nil { return false @@ -7,3 +9,20 @@ func IsNotExistsError(err error) bool { return err.Error() == "The printer or class does not exist." } + +type IPPError struct { + Status int16 + Message string +} + +func (e IPPError) Error() string { + return fmt.Sprintf("ipp status: %d, message: %s", e.Status, e.Message) +} + +type HTTPError struct { + Code int +} + +func (e HTTPError) Error() string { + return fmt.Sprintf("got http code %d", e.Code) +} diff --git a/ipp-client.go b/ipp-client.go index e36ee40..d00efab 100644 --- a/ipp-client.go +++ b/ipp-client.go @@ -83,7 +83,7 @@ func (c *IPPClient) SendRequest(url string, req *Request, additionalResponseData size := len(payload) if req.File != nil && req.FileSize != -1 { - size += int(req.FileSize) + size += req.FileSize body = io.MultiReader(bytes.NewBuffer(payload), req.File) } else { @@ -109,14 +109,29 @@ func (c *IPPClient) SendRequest(url string, req *Request, additionalResponseData defer httpResp.Body.Close() if httpResp.StatusCode != 200 { - return nil, fmt.Errorf("ipp server returned with http status code %d", httpResp.StatusCode) + return nil, HTTPError{ + Code: httpResp.StatusCode, + } } - // read the response into a temp buffer due to some wired EOF errors - // httpBody, _ := ioutil.ReadAll(httpResp.Body) - // return NewResponseDecoder(bytes.NewBuffer(httpBody)).Decode(additionalResponseData) + resp, err := NewResponseDecoder(httpResp.Body).Decode(additionalResponseData) + if err != nil { + return nil, err + } - return NewResponseDecoder(httpResp.Body).Decode(additionalResponseData) + if resp.StatusCode == StatusOk { + return resp, nil + } + + msg := "" + if statusMessage, ok := resp.OperationAttributes[AttributeStatusMessage]; ok { + msg = statusMessage[0].Value.(string) + } + + return resp, IPPError{ + Status: resp.StatusCode, + Message: msg, + } } // Print one or more `Document`s using IPP `Create-Job` followed by `Send-Document` request(s).