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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 36ac2c5fb9d968b75836ce8791362284e788566b
4
- data.tar.gz: 28d1da3d6d77f5a8c8a4d27ce1bfe6f4437e361c
3
+ metadata.gz: 4efbecc44a6f1b6d441e174b89002870d943f0c6
4
+ data.tar.gz: b26b6d1af206276ce292be1b45032833e72545a1
5
5
  SHA512:
6
- metadata.gz: 67fe62cc645b89a55c5743b8717cc7854cc59a7ba034aed0e112a9fd025c2bbfd8cdf7aae5aa329485b636f37a2e5edc6c610e62eb892b5fa102eac9e9ac826a
7
- data.tar.gz: 671bfedcf9fdc3a951b42497d707a0aed0873356980dcc2939678e0391d54dea56df228bb510f900cb262856208c35a74eb4adb52fbddb964416ab0ec9248ed0
6
+ metadata.gz: 0f659defbe116065118a2de7941d2bff3764945388fc4a1faeda85d1ef5aac1db3a0e9716b55555e04f5027efc54ffb8d7bbfd476da00bf9ff100e636255ede8
7
+ data.tar.gz: a504608277be45cbf8b6ed5df8adc5303dddf98c2d568f3717c4a73db09cee0388d66daf9c9b172e712f586824e38d52b368e7f1e3f8a9b56f78a9066e5517e9
data/README.md CHANGED
@@ -1,8 +1,45 @@
1
1
  # JsonApiErrors
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/json_api_errors`. To experiment with that code, run `bin/console` for an interactive prompt.
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
- TODO: Write usage instructions here
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
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 1.10"
31
31
  spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency 'minitest', '~> 0'
32
+ spec.add_development_dependency 'minitest'
33
33
  end
@@ -1,3 +1,3 @@
1
1
  module JsonApiErrors
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
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.2
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