cent 2.2.0 → 4.0.0
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/CHANGELOG.md +5 -0
- data/Gemfile +7 -9
- data/README.md +165 -186
- data/cent.gemspec +14 -15
- data/lib/cent/client.rb +215 -228
- data/lib/cent/error.rb +41 -4
- data/lib/cent/notary.rb +68 -59
- data/lib/cent/version.rb +1 -1
- data/lib/cent.rb +1 -1
- metadata +24 -46
- data/.github/workflows/main.yml +0 -18
- data/.github/workflows/release.yml +0 -34
- data/.gitignore +0 -20
- data/.rspec +0 -3
- data/.rubocop.yml +0 -13
- data/lib/cent/http.rb +0 -47
data/lib/cent/client.rb
CHANGED
|
@@ -1,273 +1,260 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'faraday'
|
|
4
|
-
require '
|
|
5
|
-
require 'cent/http'
|
|
4
|
+
require 'cent/error'
|
|
6
5
|
|
|
7
6
|
module Cent
|
|
8
7
|
# Cent::Client
|
|
9
8
|
#
|
|
10
|
-
#
|
|
9
|
+
# Ruby client for Centrifugo server HTTP API (Centrifugo v4+).
|
|
11
10
|
#
|
|
11
|
+
# Every API method returns the raw parsed response body from Centrifugo —
|
|
12
|
+
# typically `{ "result" => { ... } }` on success. If Centrifugo rejects the
|
|
13
|
+
# request with a top-level `error`, {Cent::ResponseError} is raised with
|
|
14
|
+
# Centrifugo's numeric `code` and `message`. Transport-level problems
|
|
15
|
+
# (network failure, timeout, non-2xx HTTP status, unparseable body) raise
|
|
16
|
+
# other {Cent::Error} subclasses.
|
|
17
|
+
#
|
|
18
|
+
# {#batch} and {#broadcast} are special: their responses contain an array
|
|
19
|
+
# of independent sub-replies, each of which may carry its own `error`
|
|
20
|
+
# field. Those sub-reply errors are NOT raised — callers inspect them
|
|
21
|
+
# manually. See {#batch} for details.
|
|
22
|
+
#
|
|
23
|
+
# @example Basic usage
|
|
24
|
+
# client = Cent::Client.new(api_key: 'secret')
|
|
25
|
+
# client.publish(channel: 'chat', data: { text: 'hi' })
|
|
26
|
+
# # => {"result" => {}}
|
|
27
|
+
#
|
|
28
|
+
# @example Custom Faraday configuration
|
|
29
|
+
# Cent::Client.new(api_key: 'k', endpoint: 'https://c.example.com/api') do |conn|
|
|
30
|
+
# conn.options.open_timeout = 3
|
|
31
|
+
# conn.options.timeout = 7
|
|
32
|
+
# conn.adapter :typhoeus
|
|
33
|
+
# end
|
|
12
34
|
class Client
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
# @
|
|
20
|
-
#
|
|
21
|
-
# @
|
|
22
|
-
|
|
23
|
-
# endpoint: 'http://localhost:8000/api',
|
|
24
|
-
# api_key: 'api key'
|
|
25
|
-
# )
|
|
26
|
-
#
|
|
27
|
-
def initialize(api_key:, endpoint: 'http://localhost:8000/api')
|
|
35
|
+
DEFAULT_ENDPOINT = 'http://localhost:8000/api'
|
|
36
|
+
DEFAULT_TIMEOUT = 10
|
|
37
|
+
|
|
38
|
+
attr_reader :connection
|
|
39
|
+
|
|
40
|
+
# @param api_key [String] Centrifugo HTTP API key (sent as `X-API-Key`).
|
|
41
|
+
# @param endpoint [String] Centrifugo HTTP API base URL.
|
|
42
|
+
# @param timeout [Numeric] Request timeout in seconds.
|
|
43
|
+
# @yield [Faraday::Connection] optional block to further configure the connection.
|
|
44
|
+
def initialize(api_key:, endpoint: DEFAULT_ENDPOINT, timeout: DEFAULT_TIMEOUT, &block)
|
|
28
45
|
headers = {
|
|
29
46
|
'Content-Type' => 'application/json',
|
|
30
|
-
'
|
|
47
|
+
'X-API-Key' => api_key
|
|
31
48
|
}
|
|
32
49
|
|
|
33
|
-
|
|
34
|
-
conn.request :json # encode req bodies as JSON
|
|
50
|
+
base = endpoint.end_with?('/') ? endpoint : "#{endpoint}/"
|
|
35
51
|
|
|
36
|
-
|
|
52
|
+
@connection = Faraday.new(base, headers: headers) do |conn|
|
|
53
|
+
conn.options.timeout = timeout
|
|
54
|
+
conn.options.open_timeout = timeout
|
|
55
|
+
conn.request :json
|
|
56
|
+
conn.response :json
|
|
37
57
|
conn.response :raise_error
|
|
38
|
-
|
|
39
|
-
yield conn if block_given?
|
|
58
|
+
block&.call(conn)
|
|
40
59
|
end
|
|
41
60
|
end
|
|
42
61
|
|
|
43
|
-
# Publish data into channel
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# @return [Hash] Return empty hash in case of successful publish
|
|
59
|
-
#
|
|
60
|
-
def publish(channel:, data:)
|
|
61
|
-
execute('publish', channel: channel, data: data)
|
|
62
|
+
# Publish data into a channel.
|
|
63
|
+
# @see https://centrifugal.dev/docs/server/server_api#publish
|
|
64
|
+
def publish(channel:, data:, skip_history: nil, tags: nil, b64data: nil,
|
|
65
|
+
idempotency_key: nil, delta: nil, version: nil, version_epoch: nil)
|
|
66
|
+
send_command('publish', {
|
|
67
|
+
'channel' => channel,
|
|
68
|
+
'data' => data,
|
|
69
|
+
'skip_history' => skip_history,
|
|
70
|
+
'tags' => tags,
|
|
71
|
+
'b64data' => b64data,
|
|
72
|
+
'idempotency_key' => idempotency_key,
|
|
73
|
+
'delta' => delta,
|
|
74
|
+
'version' => version,
|
|
75
|
+
'version_epoch' => version_epoch
|
|
76
|
+
})
|
|
62
77
|
end
|
|
63
78
|
|
|
64
|
-
# Publish data into
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def broadcast(channels:, data:)
|
|
80
|
-
execute('broadcast', channels: channels, data: data)
|
|
79
|
+
# Publish the same data into many channels.
|
|
80
|
+
# @see https://centrifugal.dev/docs/server/server_api#broadcast
|
|
81
|
+
def broadcast(channels:, data:, skip_history: nil, tags: nil, b64data: nil,
|
|
82
|
+
idempotency_key: nil, delta: nil, version: nil, version_epoch: nil)
|
|
83
|
+
send_command('broadcast', {
|
|
84
|
+
'channels' => channels,
|
|
85
|
+
'data' => data,
|
|
86
|
+
'skip_history' => skip_history,
|
|
87
|
+
'tags' => tags,
|
|
88
|
+
'b64data' => b64data,
|
|
89
|
+
'idempotency_key' => idempotency_key,
|
|
90
|
+
'delta' => delta,
|
|
91
|
+
'version' => version,
|
|
92
|
+
'version_epoch' => version_epoch
|
|
93
|
+
})
|
|
81
94
|
end
|
|
82
95
|
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
#
|
|
100
|
-
def unsubscribe(channel:, user:)
|
|
101
|
-
execute('unsubscribe', channel: channel, user: user)
|
|
96
|
+
# Subscribe a user's active session to a channel (server-side subscription).
|
|
97
|
+
# @see https://centrifugal.dev/docs/server/server_api#subscribe
|
|
98
|
+
def subscribe(user:, channel:, info: nil, b64info: nil, client: nil, session: nil,
|
|
99
|
+
data: nil, b64data: nil, recover_since: nil, override: nil)
|
|
100
|
+
send_command('subscribe', {
|
|
101
|
+
'user' => user,
|
|
102
|
+
'channel' => channel,
|
|
103
|
+
'info' => info,
|
|
104
|
+
'b64info' => b64info,
|
|
105
|
+
'client' => client,
|
|
106
|
+
'session' => session,
|
|
107
|
+
'data' => data,
|
|
108
|
+
'b64data' => b64data,
|
|
109
|
+
'recover_since' => recover_since,
|
|
110
|
+
'override' => override
|
|
111
|
+
})
|
|
102
112
|
end
|
|
103
113
|
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
# @raise [Cent::Error, Cent::ResponseError]
|
|
115
|
-
#
|
|
116
|
-
# @return [Hash] Return empty hash in case of successful disconnect
|
|
117
|
-
#
|
|
118
|
-
def disconnect(user:)
|
|
119
|
-
execute('disconnect', user: user)
|
|
114
|
+
# Unsubscribe a user from a channel.
|
|
115
|
+
# @see https://centrifugal.dev/docs/server/server_api#unsubscribe
|
|
116
|
+
def unsubscribe(user:, channel:, client: nil, session: nil)
|
|
117
|
+
send_command('unsubscribe', {
|
|
118
|
+
'user' => user,
|
|
119
|
+
'channel' => channel,
|
|
120
|
+
'client' => client,
|
|
121
|
+
'session' => session
|
|
122
|
+
})
|
|
120
123
|
end
|
|
121
124
|
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
#
|
|
147
|
-
# @
|
|
148
|
-
# Return hash with information about all clients currently subscribed on this channel
|
|
149
|
-
#
|
|
125
|
+
# Disconnect a user by ID.
|
|
126
|
+
# @see https://centrifugal.dev/docs/server/server_api#disconnect
|
|
127
|
+
def disconnect(user:, client: nil, session: nil, whitelist: nil, disconnect: nil)
|
|
128
|
+
send_command('disconnect', {
|
|
129
|
+
'user' => user,
|
|
130
|
+
'client' => client,
|
|
131
|
+
'session' => session,
|
|
132
|
+
'whitelist' => whitelist,
|
|
133
|
+
'disconnect' => disconnect
|
|
134
|
+
})
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Refresh a user connection (for unidirectional transports).
|
|
138
|
+
# @see https://centrifugal.dev/docs/server/server_api#refresh
|
|
139
|
+
def refresh(user:, client: nil, session: nil, expired: nil, expire_at: nil)
|
|
140
|
+
send_command('refresh', {
|
|
141
|
+
'user' => user,
|
|
142
|
+
'client' => client,
|
|
143
|
+
'session' => session,
|
|
144
|
+
'expired' => expired,
|
|
145
|
+
'expire_at' => expire_at
|
|
146
|
+
})
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Get channel presence (all currently subscribed clients).
|
|
150
|
+
# @see https://centrifugal.dev/docs/server/server_api#presence
|
|
150
151
|
def presence(channel:)
|
|
151
|
-
|
|
152
|
+
send_command('presence', { 'channel' => channel })
|
|
152
153
|
end
|
|
153
154
|
|
|
154
|
-
# Get short
|
|
155
|
-
#
|
|
156
|
-
# @param channel [String] Name of the channel
|
|
157
|
-
#
|
|
158
|
-
# @example Get short presence information for channel `chat`
|
|
159
|
-
# client.presence_stats(channel: 'chat') #=> {
|
|
160
|
-
# "result" => {
|
|
161
|
-
# "num_clients" => 0,
|
|
162
|
-
# "num_users" => 0
|
|
163
|
-
# }
|
|
164
|
-
# }
|
|
165
|
-
#
|
|
166
|
-
# @see (https://centrifugal.github.io/centrifugo/server/http_api/#presence_stats)
|
|
167
|
-
#
|
|
168
|
-
# @raise [Cent::Error, Cent::ResponseError]
|
|
169
|
-
#
|
|
170
|
-
# @return [Hash]
|
|
171
|
-
# Return hash with short presence information about channel
|
|
172
|
-
#
|
|
155
|
+
# Get short presence stats for a channel.
|
|
156
|
+
# @see https://centrifugal.dev/docs/server/server_api#presence_stats
|
|
173
157
|
def presence_stats(channel:)
|
|
174
|
-
|
|
158
|
+
send_command('presence_stats', { 'channel' => channel })
|
|
175
159
|
end
|
|
176
160
|
|
|
177
|
-
# Get channel history
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
# {
|
|
187
|
-
# "data" => {
|
|
188
|
-
# "text" => "hello"
|
|
189
|
-
# },
|
|
190
|
-
# "uid" => "BWcn14OTBrqUhTXyjNg0fg"
|
|
191
|
-
# },
|
|
192
|
-
# {
|
|
193
|
-
# "data" => {
|
|
194
|
-
# "text" => "hi!"
|
|
195
|
-
# },
|
|
196
|
-
# "uid" => "Ascn14OTBrq14OXyjNg0hg"
|
|
197
|
-
# }
|
|
198
|
-
# ]
|
|
199
|
-
# }
|
|
200
|
-
# }
|
|
201
|
-
#
|
|
202
|
-
# @see (https://centrifugal.github.io/centrifugo/server/http_api/#history)
|
|
203
|
-
#
|
|
204
|
-
# @raise [Cent::Error, Cent::ResponseError]
|
|
205
|
-
#
|
|
206
|
-
# @return [Hash]
|
|
207
|
-
# Return hash with a list of last messages published into channel
|
|
208
|
-
#
|
|
209
|
-
def history(channel:)
|
|
210
|
-
execute('history', channel: channel)
|
|
161
|
+
# Get channel history (recent publications).
|
|
162
|
+
# @see https://centrifugal.dev/docs/server/server_api#history
|
|
163
|
+
def history(channel:, limit: nil, since: nil, reverse: nil)
|
|
164
|
+
send_command('history', {
|
|
165
|
+
'channel' => channel,
|
|
166
|
+
'limit' => limit,
|
|
167
|
+
'since' => since,
|
|
168
|
+
'reverse' => reverse
|
|
169
|
+
})
|
|
211
170
|
end
|
|
212
171
|
|
|
213
|
-
#
|
|
214
|
-
#
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
# "result" => {
|
|
218
|
-
# "channels" => [
|
|
219
|
-
# "chat"
|
|
220
|
-
# ]
|
|
221
|
-
# }
|
|
222
|
-
# }
|
|
223
|
-
#
|
|
224
|
-
# @see (https://centrifugal.github.io/centrifugo/server/http_api/#channels)
|
|
225
|
-
#
|
|
226
|
-
# @raise [Cent::Error, Cent::ResponseError]
|
|
227
|
-
#
|
|
228
|
-
# @return [Hash]
|
|
229
|
-
# Return hash with a list of active channels
|
|
230
|
-
#
|
|
231
|
-
def channels
|
|
232
|
-
execute('channels', {})
|
|
172
|
+
# Remove all publications from a channel's history.
|
|
173
|
+
# @see https://centrifugal.dev/docs/server/server_api#history_remove
|
|
174
|
+
def history_remove(channel:)
|
|
175
|
+
send_command('history_remove', { 'channel' => channel })
|
|
233
176
|
end
|
|
234
177
|
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
#
|
|
242
|
-
#
|
|
243
|
-
# "num_channels" => 0,
|
|
244
|
-
# "num_clients" => 0,
|
|
245
|
-
# "num_users" => 0,
|
|
246
|
-
# "uid" => "f844a2ed-5edf-4815-b83c-271974003db9",
|
|
247
|
-
# "uptime" => 0,
|
|
248
|
-
# "version" => ""
|
|
249
|
-
# }
|
|
250
|
-
# ]
|
|
251
|
-
# }
|
|
252
|
-
# }
|
|
253
|
-
#
|
|
254
|
-
# @see (https://centrifugal.github.io/centrifugo/server/http_api/#info)
|
|
255
|
-
#
|
|
256
|
-
# @raise [Cent::Error, Cent::ResponseError]
|
|
257
|
-
#
|
|
258
|
-
# @return [Hash]
|
|
259
|
-
# Return hash with a list of last messages published into channel
|
|
260
|
-
#
|
|
178
|
+
# List active channels (channels with at least one subscriber).
|
|
179
|
+
# @see https://centrifugal.dev/docs/server/server_api#channels
|
|
180
|
+
def channels(pattern: nil)
|
|
181
|
+
send_command('channels', { 'pattern' => pattern })
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Get information about running Centrifugo nodes.
|
|
185
|
+
# @see https://centrifugal.dev/docs/server/server_api#info
|
|
261
186
|
def info
|
|
262
|
-
|
|
187
|
+
send_command('info', {})
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Send many commands in a single request.
|
|
191
|
+
#
|
|
192
|
+
# The response is shaped `{ "replies" => [<reply>, ...] }` — note there
|
|
193
|
+
# is no top-level `result` wrapper, unlike every other method. Each reply
|
|
194
|
+
# in the array corresponds to one command (in the order they were sent
|
|
195
|
+
# when `parallel` is not set) and has the shape `{ "<method>" => <result> }`
|
|
196
|
+
# on success or `{ "error" => { "code" => ..., "message" => ... } }` on a
|
|
197
|
+
# per-command failure.
|
|
198
|
+
#
|
|
199
|
+
# These per-command errors are **not** raised as {Cent::ResponseError} —
|
|
200
|
+
# that would make partial-failure responses impossible to inspect. The
|
|
201
|
+
# caller is expected to walk `response["replies"]` and check each entry.
|
|
202
|
+
# If Centrifugo rejects the batch request as a whole (e.g. malformed
|
|
203
|
+
# top-level body), the top-level `error` field is present and
|
|
204
|
+
# {Cent::ResponseError} is raised normally.
|
|
205
|
+
#
|
|
206
|
+
# @example
|
|
207
|
+
# response = client.batch(commands: [
|
|
208
|
+
# { 'publish' => { 'channel' => 'a', 'data' => {} } },
|
|
209
|
+
# { 'publish' => { 'channel' => 'unknown:b', 'data' => {} } }
|
|
210
|
+
# ])
|
|
211
|
+
# response['replies'].each do |reply|
|
|
212
|
+
# if reply['error']
|
|
213
|
+
# warn "command failed: #{reply['error']['code']} #{reply['error']['message']}"
|
|
214
|
+
# end
|
|
215
|
+
# end
|
|
216
|
+
#
|
|
217
|
+
# @param commands [Array<Hash>] Each element is a command object of the
|
|
218
|
+
# form `{ "publish" => { ... } }`, `{ "broadcast" => { ... } }`, etc.
|
|
219
|
+
# @param parallel [Boolean, nil] When true, Centrifugo processes commands
|
|
220
|
+
# in parallel (lower latency, order not guaranteed).
|
|
221
|
+
# @see https://centrifugal.dev/docs/server/server_api#batch
|
|
222
|
+
def batch(commands:, parallel: nil)
|
|
223
|
+
send_command('batch', {
|
|
224
|
+
'commands' => commands,
|
|
225
|
+
'parallel' => parallel
|
|
226
|
+
})
|
|
263
227
|
end
|
|
264
228
|
|
|
265
229
|
private
|
|
266
230
|
|
|
267
|
-
def
|
|
268
|
-
body =
|
|
231
|
+
def send_command(method, params)
|
|
232
|
+
body = connection.post(method, params.compact).body
|
|
233
|
+
check_response_error!(body)
|
|
234
|
+
body
|
|
235
|
+
rescue Faraday::TimeoutError => e
|
|
236
|
+
raise Cent::TimeoutError, e.message
|
|
237
|
+
rescue Faraday::ConnectionFailed => e
|
|
238
|
+
raise Cent::NetworkError, e.message
|
|
239
|
+
rescue Faraday::UnauthorizedError => e
|
|
240
|
+
raise Cent::UnauthorizedError.new(status: 401, message: e.message)
|
|
241
|
+
rescue Faraday::ClientError, Faraday::ServerError => e
|
|
242
|
+
status = e.response_status || e.response&.dig(:status)
|
|
243
|
+
raise Cent::TransportError.new(status: status, message: e.message)
|
|
244
|
+
rescue Faraday::ParsingError => e
|
|
245
|
+
raise Cent::DecodeError, e.message
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Top-level `error` means Centrifugo rejected the whole request. Batch
|
|
249
|
+
# and broadcast sub-reply errors live inside arrays and are NOT raised —
|
|
250
|
+
# callers inspect them manually (see #batch docs).
|
|
251
|
+
def check_response_error!(body)
|
|
252
|
+
return unless body.is_a?(Hash) && body['error'].is_a?(Hash)
|
|
269
253
|
|
|
270
|
-
Cent::
|
|
254
|
+
raise Cent::ResponseError.new(
|
|
255
|
+
code: body['error']['code'],
|
|
256
|
+
message: body['error']['message']
|
|
257
|
+
)
|
|
271
258
|
end
|
|
272
259
|
end
|
|
273
260
|
end
|
data/lib/cent/error.rb
CHANGED
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Cent
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Wrapper for all errors(failures).
|
|
7
|
-
#
|
|
4
|
+
# Base class for all errors raised by this library.
|
|
8
5
|
class Error < StandardError; end
|
|
6
|
+
|
|
7
|
+
# Raised when Centrifugo is unreachable (DNS failure, connection refused, ...).
|
|
8
|
+
class NetworkError < Error; end
|
|
9
|
+
|
|
10
|
+
# Raised when the HTTP request times out.
|
|
11
|
+
class TimeoutError < Error; end
|
|
12
|
+
|
|
13
|
+
# Raised when Centrifugo returns a non-2xx HTTP status.
|
|
14
|
+
class TransportError < Error
|
|
15
|
+
attr_reader :status
|
|
16
|
+
|
|
17
|
+
def initialize(status:, message: nil)
|
|
18
|
+
@status = status
|
|
19
|
+
super(message || "HTTP #{status}")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Raised when Centrifugo returns HTTP 401 (invalid API key).
|
|
24
|
+
class UnauthorizedError < TransportError; end
|
|
25
|
+
|
|
26
|
+
# Raised when response from Centrifugo cannot be decoded (not valid JSON).
|
|
27
|
+
class DecodeError < Error; end
|
|
28
|
+
|
|
29
|
+
# Raised when Centrifugo returns a top-level `error` in the response body
|
|
30
|
+
# (API-level failure, e.g., unknown channel, namespace not found). Exposes
|
|
31
|
+
# Centrifugo's numeric `code` and human-readable `message`. See
|
|
32
|
+
# https://centrifugal.dev/docs/server/server_api#error for the full list
|
|
33
|
+
# of codes.
|
|
34
|
+
#
|
|
35
|
+
# Note: for `batch` and `broadcast`, individual sub-reply errors are NOT
|
|
36
|
+
# raised — those responses contain an array of independent replies, and
|
|
37
|
+
# each entry should be inspected by the caller for its own `error` key.
|
|
38
|
+
class ResponseError < Error
|
|
39
|
+
attr_reader :code
|
|
40
|
+
|
|
41
|
+
def initialize(code:, message:)
|
|
42
|
+
@code = code
|
|
43
|
+
super(message)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
9
46
|
end
|