Commit e44b1aa2 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Simplify errors

parent cd5c2b18
......@@ -23,10 +23,11 @@ type ErrorCode string
// Error is a protocol error.
type Error struct {
ErrorCode
error
info string
ErrorCode
*ApiError
Info string
Status int
}
// Statuses
......@@ -57,17 +58,23 @@ const (
ErrorCrypto = ErrorCode("cryptoResponseError")
// Server rejected our response (second IRMA message)
ErrorRejected = ErrorCode("rejectedByServer")
// (De)serializing of a message failed
ErrorSerialization = ErrorCode("serializationError")
)
// Qr contains the data of an IRMA session QR.
// Qr contains the data of an IRMA session QR (as generated by irma_js),
// suitable for NewSession().
type Qr struct {
URL string `json:"u"`
// Server with which to perform the session
URL string `json:"u"`
// Session type (disclosing, signing, issuing)
Type Action `json:"irmaqr"`
ProtocolVersion string `json:"v"`
ProtocolMaxVersion string `json:"vmax"`
Type Action `json:"irmaqr"`
}
// A SessionInfo is the first message in the IRMA protocol.
// A SessionInfo is the first message in the IRMA protocol (i.e., GET on the server URL),
// containing the session request info.
type SessionInfo struct {
Jwt string `json:"jwt"`
Nonce *big.Int `json:"nonce"`
......
......@@ -47,5 +47,7 @@ func TestTransport(t *testing.T) {
}{}
err := transport.Get("614/info.0.json", obj)
require.NoError(t, err)
if err != nil { // require.NoError() does not work because of the type of err
t.Fatalf("%+v\n", err)
}
}
......@@ -106,7 +106,7 @@ func NewSession(qr *Qr, handler Handler) {
case ActionUnknown:
fallthrough
default:
handler.Failure(ActionUnknown, &Error{ErrorCode: ErrorUnknownAction, error: nil, info: string(session.Action)})
handler.Failure(ActionUnknown, &Error{ErrorCode: ErrorUnknownAction, error: nil, Info: string(session.Action)})
return
}
......@@ -126,9 +126,9 @@ func (session *session) start() {
// Get the first IRMA protocol message and parse it
info := &SessionInfo{}
err := session.transport.Get("jwt", info)
if err != nil {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorTransport, ApiError: err.(*TransportError).ApiErr})
Err := session.transport.Get("jwt", info)
if Err != nil {
session.Handler.Failure(session.Action, Err)
return
}
jwtparts := strings.Split(info.Jwt, ".")
......@@ -231,33 +231,32 @@ func (session *session) do(proceed bool, choice *irmago.DisclosureChoice) {
return
}
var Err *Error
switch session.Action {
case ActionSigning:
fallthrough
case ActionDisclosing:
response := ""
err = session.transport.Post("proofs", &response, message)
if err != nil {
session.Handler.Failure(session.Action,
&Error{ErrorCode: ErrorTransport, ApiError: err.(*TransportError).ApiErr, info: err.Error(), error: err})
Err = session.transport.Post("proofs", &response, message)
if Err != nil {
session.Handler.Failure(session.Action, Err)
return
}
if response != "VALID" {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorRejected, info: response})
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorRejected, Info: response})
return
}
case ActionIssuing:
response := []*gabi.IssueSignatureMessage{}
err = session.transport.Post("commitments", &response, message)
if err != nil {
session.Handler.Failure(session.Action,
&Error{ErrorCode: ErrorTransport, ApiError: err.(*TransportError).ApiErr, info: err.Error(), error: err})
Err = session.transport.Post("commitments", &response, message)
if Err != nil {
session.Handler.Failure(session.Action, Err)
return
}
err = irmago.Manager.ConstructCredentials(response, session.irmaSession.(*irmago.IssuanceRequest))
if err != nil {
session.Handler.Failure(session.Action, &Error{ErrorCode: ErrorCrypto, error: err})
session.Handler.Failure(session.Action, &Error{error: err, ErrorCode: ErrorCrypto})
return
}
}
......
......@@ -192,7 +192,7 @@ func sessionHelper(t *testing.T, jwtcontents interface{}, url string) {
jwt := base64.RawStdEncoding.EncodeToString(headerbytes) + "." + base64.RawStdEncoding.EncodeToString(bodybytes) + "."
qr, transportErr := StartSession(jwt, url)
if transportErr != nil {
fmt.Println(transportErr.(*TransportError).ApiErr)
fmt.Printf("+%v\n", transportErr)
}
require.NoError(t, transportErr)
qr.URL = url + "/" + qr.URL
......
......@@ -25,17 +25,6 @@ type ApiError struct {
Stacktrace string `json:"stacktrace"`
}
// TransportError is an error occuring during HTTP traffic.
type TransportError struct {
Err string
Status int
ApiErr *ApiError
}
func (te TransportError) Error() string {
return te.Err
}
// NewHTTPTransport returns a new HTTPTransport.
func NewHTTPTransport(serverURL string) *HTTPTransport {
url := serverURL
......@@ -50,7 +39,7 @@ func NewHTTPTransport(serverURL string) *HTTPTransport {
}
}
func (transport *HTTPTransport) request(url string, method string, result interface{}, object interface{}) error {
func (transport *HTTPTransport) request(url string, method string, result interface{}, object interface{}) *Error {
if method != http.MethodPost && method != http.MethodGet {
panic("Unsupported HTTP method " + method)
}
......@@ -67,7 +56,8 @@ func (transport *HTTPTransport) request(url string, method string, result interf
} else {
marshaled, err := json.Marshal(object)
if err != nil {
return &TransportError{Err: err.Error()}
return &Error{error: err, ErrorCode: ErrorSerialization}
//return &TransportError{Err: err.Error()}
}
//fmt.Printf("POST: %s\n", string(marshaled))
reader = bytes.NewBuffer(marshaled)
......@@ -76,7 +66,7 @@ func (transport *HTTPTransport) request(url string, method string, result interf
req, err := http.NewRequest(method, transport.Server+url, reader)
if err != nil {
return &TransportError{Err: err.Error()}
return &Error{error: err, ErrorCode: ErrorTransport}
}
req.Header.Set("User-Agent", "irmago")
......@@ -90,39 +80,39 @@ func (transport *HTTPTransport) request(url string, method string, result interf
res, err := transport.client.Do(req)
if err != nil {
return &TransportError{Err: err.Error()}
return &Error{error: err, ErrorCode: ErrorTransport}
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return &TransportError{Err: err.Error(), Status: res.StatusCode}
return &Error{error: err, Status: res.StatusCode}
}
if res.StatusCode != 200 {
apierr := &ApiError{}
json.Unmarshal(body, apierr)
if apierr.ErrorName == "" { // Not an ApiErrorMessage
return &TransportError{Status: res.StatusCode}
return &Error{ErrorCode: ErrorTransport, Status: res.StatusCode}
}
//fmt.Printf("ERROR: %+v\n", apierr)
return &TransportError{Err: apierr.ErrorName, Status: res.StatusCode, ApiErr: apierr}
return &Error{ErrorCode: ErrorTransport, Status: res.StatusCode, ApiError: apierr}
}
//fmt.Printf("RESPONSE: %s\n", string(body))
err = json.Unmarshal(body, result)
if err != nil {
return &TransportError{Err: err.Error(), Status: res.StatusCode}
return &Error{error: err, Status: res.StatusCode}
}
return nil
}
// Post sends the object to the server and parses its response into result.
func (transport *HTTPTransport) Post(url string, result interface{}, object interface{}) error {
func (transport *HTTPTransport) Post(url string, result interface{}, object interface{}) *Error {
return transport.request(url, http.MethodPost, result, object)
}
// Get performs a GET request and parses the server's response into result.
func (transport *HTTPTransport) Get(url string, result interface{}) error {
func (transport *HTTPTransport) Get(url string, result interface{}) *Error {
return transport.request(url, http.MethodGet, result, nil)
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment