Skip to content

Commit a1fcd33

Browse files
authored
DE-1332 Fix RFC2822Time Unmarshal (#329)
1 parent a7b6ae6 commit a1fcd33

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

rfc2822.go

+13-9
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package mailgun
22

33
import (
44
"strconv"
5-
"strings"
65
"time"
6+
7+
"github.com/pkg/errors"
78
)
89

9-
// Mailgun uses RFC2822 format for timestamps everywhere ('Thu, 13 Oct 2011 18:02:00 GMT'), but
10+
// RFC2822Time Mailgun uses RFC2822 format for timestamps everywhere ('Thu, 13 Oct 2011 18:02:00 GMT'), but
1011
// by default Go's JSON package uses another format when decoding/encoding timestamps.
1112
type RFC2822Time time.Time
1213

@@ -35,15 +36,18 @@ func (t *RFC2822Time) UnmarshalJSON(s []byte) error {
3536
if err != nil {
3637
return err
3738
}
38-
if *(*time.Time)(t), err = time.Parse(time.RFC1123, q); err != nil {
39-
if strings.Contains(err.Error(), "extra text") {
40-
if *(*time.Time)(t), err = time.Parse(time.RFC1123Z, q); err != nil {
41-
return err
42-
}
43-
return nil
39+
40+
var err1 error
41+
*(*time.Time)(t), err1 = time.Parse(time.RFC1123, q)
42+
if err1 != nil {
43+
var err2 error
44+
*(*time.Time)(t), err2 = time.Parse(time.RFC1123Z, q)
45+
if err2 != nil {
46+
// TODO(go1.20): use errors.Join:
47+
return errors.Errorf("%s; %s", err1, err2)
4448
}
45-
return err
4649
}
50+
4751
return nil
4852
}
4953

rfc2822_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package mailgun
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"testing"
7+
"time"
8+
9+
"github.com/facebookgo/ensure"
10+
)
11+
12+
func TestUnmarshalRFC2822Time(t *testing.T) {
13+
type Req struct {
14+
CreatedAt RFC2822Time `json:"created_at"`
15+
}
16+
17+
tests := []struct {
18+
name string
19+
s string
20+
want Req
21+
wantErr bool
22+
}{
23+
{
24+
name: "RFC1123",
25+
s: `{"created_at":"Thu, 13 Oct 2011 18:02:00 GMT"}`,
26+
wantErr: false,
27+
want: Req{CreatedAt: RFC2822Time(time.Date(2011, 10, 13, 18, 2, 0, 0, time.UTC))},
28+
},
29+
{
30+
name: "RFC1123Z",
31+
s: `{"created_at":"Thu, 13 Oct 2011 18:02:00 +0000"}`,
32+
wantErr: false,
33+
want: Req{CreatedAt: RFC2822Time(time.Date(2011, 10, 13, 18, 2, 0, 0, time.UTC))},
34+
},
35+
}
36+
37+
for _, tt := range tests {
38+
t.Run(tt.name, func(t *testing.T) {
39+
var req Req
40+
err := json.Unmarshal([]byte(tt.s), &req)
41+
if (err != nil) != tt.wantErr {
42+
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
43+
}
44+
45+
ensure.True(t, time.Time(tt.want.CreatedAt).Equal(time.Time(req.CreatedAt)),
46+
fmt.Sprintf("want: %s; got: %s", tt.want.CreatedAt, req.CreatedAt))
47+
})
48+
}
49+
}

0 commit comments

Comments
 (0)