json_api_errors 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +214 -4
- data/json_api_errors-0.1.2.gem +0 -0
- data/json_api_errors-0.1.3.gem +0 -0
- data/json_api_errors.gemspec +1 -1
- data/lib/json_api_errors/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4efbecc44a6f1b6d441e174b89002870d943f0c6
|
4
|
+
data.tar.gz: b26b6d1af206276ce292be1b45032833e72545a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f659defbe116065118a2de7941d2bff3764945388fc4a1faeda85d1ef5aac1db3a0e9716b55555e04f5027efc54ffb8d7bbfd476da00bf9ff100e636255ede8
|
7
|
+
data.tar.gz: a504608277be45cbf8b6ed5df8adc5303dddf98c2d568f3717c4a73db09cee0388d66daf9c9b172e712f586824e38d52b368e7f1e3f8a9b56f78a9066e5517e9
|
data/README.md
CHANGED
@@ -1,8 +1,45 @@
|
|
1
1
|
# JsonApiErrors
|
2
2
|
|
3
|
-
|
3
|
+
Handling errors gracefully is pretty awesome.
|
4
|
+
|
5
|
+
I was having a hard time at that and so one of the steps I took was to create a simple
|
6
|
+
error object, one that adhered to the Json API Error spec, not coupled to any other
|
7
|
+
library.
|
8
|
+
|
9
|
+
Not all errors need to be handled gracefully, but for those that do its nice to
|
10
|
+
see a response formatted in a way like it doesn't feel your world is
|
11
|
+
crashing down (even though it is!):
|
12
|
+
|
13
|
+
```json
|
14
|
+
{
|
15
|
+
"errors": [
|
16
|
+
{
|
17
|
+
"id": "10002",
|
18
|
+
"status": "400",
|
19
|
+
"links": {
|
20
|
+
"about": "www.info-about-the-error.org"
|
21
|
+
},
|
22
|
+
"code": "Bad Request",
|
23
|
+
"title": "Your request didn't have a title attribute.",
|
24
|
+
"detail": "Oopps! You'll need to add a title before you can proceed.",
|
25
|
+
"source": {
|
26
|
+
"pointer": "/data/attribute/title",
|
27
|
+
"parameter": "title"
|
28
|
+
},
|
29
|
+
"meta": {
|
30
|
+
"extra_info": "Here's a lollypop!"
|
31
|
+
}
|
32
|
+
}
|
33
|
+
]
|
34
|
+
}
|
35
|
+
```
|
36
|
+
While it's nice to have an easy way to build errors, this project was mainly an
|
37
|
+
excuse to play around with object-oriented and functional concepts in Ruby. Because
|
38
|
+
errors are highly variable, a reusable solution called for using concepts like
|
39
|
+
dependency injection and composition. The idea of using blocks, callables, and building up the error object naturally came on later.
|
40
|
+
|
41
|
+
I hope this is at least of some use to you or that it inspires you to make something even better.
|
4
42
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
43
|
|
7
44
|
## Installation
|
8
45
|
|
@@ -22,7 +59,181 @@ Or install it yourself as:
|
|
22
59
|
|
23
60
|
## Usage
|
24
61
|
|
25
|
-
|
62
|
+
So you want an error object? Well, all you need to do is this:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
error = JsonApiErrors::Error.new
|
66
|
+
|
67
|
+
#<JsonApiErrors::Error:0x007ff753941ce8
|
68
|
+
@code=#<JsonApiErrors::Default::Code:0x007ff7539416a8>,
|
69
|
+
@detail=#<JsonApiErrors::Default::Detail:0x007ff7539414c8>,
|
70
|
+
@error=#<JsonApiErrors::Default::Error:0x007ff753941c20>,
|
71
|
+
@id=#<JsonApiErrors::Default::Id:0x007ff753941b58>,
|
72
|
+
@links=#<JsonApiErrors::Default::Links:0x007ff753941680>,
|
73
|
+
@meta=#<JsonApiErrors::Default::Meta:0x007ff753941428>,
|
74
|
+
@source=#<JsonApiErrors::Default::Source:0x007ff753941478>,
|
75
|
+
@status=#<JsonApiErrors::Default::Status:0x007ff753941b30>,
|
76
|
+
@title=#<JsonApiErrors::Default::Title:0x007ff753941568>>
|
77
|
+
```
|
78
|
+
|
79
|
+
A `JsonApiError::Error` implements `#call`. So to get a hash representation
|
80
|
+
of your error, which can be serialized into JSON, you need to send the `#call`
|
81
|
+
message to your error object:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
error.call
|
85
|
+
|
86
|
+
{:id=>"default-id",
|
87
|
+
:links=>{:about=>"default-links"},
|
88
|
+
:status=>"422",
|
89
|
+
:code=>"default-code",
|
90
|
+
:title=>"default-title",
|
91
|
+
:detail=>"default-detail",
|
92
|
+
:source=>{:pointer=>"default-pointer", :parameter=>"default-parameter"},
|
93
|
+
:meta=>{:extra_info=>"default-meta"}}
|
94
|
+
```
|
95
|
+
All those defaults suck!
|
96
|
+
|
97
|
+
Yup. The [Json API spec](http://jsonapi.org/format/#error-objects) says that all those keys and values are OPTIONAL as defined by the RFC [Key words for use in RFCs to Indicate Requirement Levels](http://tools.ietf.org/html/rfc2119). These are all placeholders for the actual keys and values you care about including in your error response. So how do you create and error object that is actually meaningful to your situation?
|
98
|
+
|
99
|
+
The easiest way is probably to use a block with literal values to define the
|
100
|
+
attributes you want to send in your response:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
error = JsonApiErrors::Error.new do |config|
|
104
|
+
config.id = "90210"
|
105
|
+
config.status = "500"
|
106
|
+
config.code = "your-internal-server-error-app-code"
|
107
|
+
config.title = "Oh my!"
|
108
|
+
config.detail = "If I knew what happened I would tell you"
|
109
|
+
config.links = { about: "www.example.com" }
|
110
|
+
config.source = { pointer: "data/attributes/hmm", parameter: "hmm" }
|
111
|
+
config.meta = { sunshine: "It feels nice" }
|
112
|
+
end
|
113
|
+
|
114
|
+
error.call
|
115
|
+
|
116
|
+
{:id=>"90210",
|
117
|
+
:links=>{:about=>"www.example.com"},
|
118
|
+
:status=>"500",
|
119
|
+
:code=>"your-internal-server-error-app-code",
|
120
|
+
:title=>"Oh my!",
|
121
|
+
:detail=>"If I knew what happened I would tell you",
|
122
|
+
:source=>{:pointer=>"data/attributes/hmm", :parameter=>"hmm"},
|
123
|
+
:meta=>{:sunshine=>"It feels nice"}}
|
124
|
+
```
|
125
|
+
|
126
|
+
Now let's say you only want to send back the status and the code attributes:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
error = JsonApiErrors::Error.new do |config|
|
130
|
+
config.id = "90210"
|
131
|
+
config.status = "500"
|
132
|
+
end
|
133
|
+
|
134
|
+
error.call
|
135
|
+
|
136
|
+
{:id=>"90210",
|
137
|
+
:links=>{:about=>"default-links"},
|
138
|
+
:status=>"500",
|
139
|
+
:code=>"default-code",
|
140
|
+
:title=>"default-title",
|
141
|
+
:detail=>"default-detail",
|
142
|
+
:source=>{:pointer=>"default-pointer", :parameter=>"default-parameter"},
|
143
|
+
:meta=>{:extra_info=>"default-meta"}}
|
144
|
+
```
|
145
|
+
|
146
|
+
Gross. Let's modify the template the error object uses to generate the hash
|
147
|
+
representation:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
template = ->(error) do
|
151
|
+
{
|
152
|
+
status: error.status,
|
153
|
+
code: error.code
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
error = JsonApiErrors::Error.new do |config|
|
158
|
+
config.error = template
|
159
|
+
config.code = "my-apps-custom-error-code"
|
160
|
+
config.status = "500"
|
161
|
+
end
|
162
|
+
|
163
|
+
error.call
|
164
|
+
|
165
|
+
{
|
166
|
+
:status=>"500",
|
167
|
+
:code=>"my-apps-custom-error-code"
|
168
|
+
}
|
169
|
+
```
|
170
|
+
|
171
|
+
Nice! We passed in a lambda as a template. I said previously that the `JsonApiErrors::Error` implements `#call`. Well, that method is delegated to
|
172
|
+
the error template's `#call` method. So instead of a lambda you could have
|
173
|
+
created a class which implements `#call` and accepts an error object as an
|
174
|
+
argument and then injected it into the initializer:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
class CustomTemplate
|
178
|
+
def call(error)
|
179
|
+
{
|
180
|
+
status: error.status.to_s,
|
181
|
+
code: error.code.to_s
|
182
|
+
}
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
error = JsonApiErrors::Error.new( error: CustomTemplate.new ) do |config|
|
187
|
+
config.code = "my-apps-custom-error-code"
|
188
|
+
config.status = "500"
|
189
|
+
end
|
190
|
+
|
191
|
+
error.call
|
192
|
+
|
193
|
+
{
|
194
|
+
:status=>"500",
|
195
|
+
:code=>"my-apps-custom-error-code"
|
196
|
+
}
|
197
|
+
```
|
198
|
+
In fact, all the properties of `JsonApiErrors::Error` are available as keyword
|
199
|
+
arguments, so you could inject all the dependencies into the initializer. Or
|
200
|
+
just as well use the `config` object in the block to customize everything to
|
201
|
+
your liking.
|
202
|
+
|
203
|
+
Note that certain config options take strings while others take hashes. If you
|
204
|
+
decide to create a class to represent a particular attribute, you'll need to
|
205
|
+
override either the `#to_s` or `#to_h`. (This project was built using Ruby 2.2.2)
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
class CustomLinks
|
209
|
+
def to_h
|
210
|
+
{ about: "www.i-am-hash.com" }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class CustomTitle
|
215
|
+
def to_s
|
216
|
+
"i-am-title"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
```
|
220
|
+
|
221
|
+
The [Json API spec](http://jsonapi.org/format/#error-objects) mentions that all
|
222
|
+
errors MUST have the keyword `errors` at the root. For this purpose there is
|
223
|
+
`JsonApiError::ErrorCollection`. To get a fully qualified hash representation
|
224
|
+
of your error you can:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
collection = JsonApiErrors::ErrorCollection.new
|
228
|
+
collection.add_error(error)
|
229
|
+
collection.call
|
230
|
+
|
231
|
+
{:errors=>[
|
232
|
+
{
|
233
|
+
:status=>"500",
|
234
|
+
:code=>"my-apps-custom-error-code" }]}
|
235
|
+
|
236
|
+
```
|
26
237
|
|
27
238
|
## Development
|
28
239
|
|
@@ -38,4 +249,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
|
|
38
249
|
## License
|
39
250
|
|
40
251
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
-
|
Binary file
|
Binary file
|
data/json_api_errors.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_api_errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- byelipk
|
@@ -42,14 +42,14 @@ dependencies:
|
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
description: While building out a backend server I realized a needed a simple way
|
@@ -70,6 +70,8 @@ files:
|
|
70
70
|
- Rakefile
|
71
71
|
- bin/console
|
72
72
|
- bin/setup
|
73
|
+
- json_api_errors-0.1.2.gem
|
74
|
+
- json_api_errors-0.1.3.gem
|
73
75
|
- json_api_errors.gemspec
|
74
76
|
- lib/json_api_errors.rb
|
75
77
|
- lib/json_api_errors/default/code.rb
|