startback-websocket 0.14.0 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/README.md +64 -9
- data/lib/startback/ext/context.rb +6 -0
- data/lib/startback/ext.rb +1 -2
- data/lib/startback/websocket/app.rb +82 -0
- data/lib/startback/websocket/hub/app.rb +28 -0
- data/lib/startback/websocket/hub/builder.rb +55 -0
- data/lib/startback/websocket/hub/errors.rb +9 -0
- data/lib/startback/websocket/hub/message.rb +29 -0
- data/lib/startback/websocket/hub/middleware/command_handler.rb +34 -0
- data/lib/startback/websocket/hub/middleware/room_handler.rb +30 -0
- data/lib/startback/websocket/hub/middleware.rb +12 -0
- data/lib/startback/websocket/hub/participant.rb +16 -0
- data/lib/startback/websocket/hub/room.rb +46 -0
- data/lib/startback/websocket/hub.rb +15 -0
- data/lib/startback/websocket.rb +8 -0
- data/spec/spec_helper.rb +21 -32
- data/spec/unit/hub/test_builder.rb +141 -0
- data/spec/unit/hub/test_room.rb +27 -0
- data/spec/unit/test_app.rb +35 -0
- data/tasks/test.rake +0 -1
- metadata +20 -91
- data/lib/startback/audit/prometheus.rb +0 -87
- data/lib/startback/audit/shared.rb +0 -17
- data/lib/startback/audit/trailer.rb +0 -129
- data/lib/startback/audit.rb +0 -3
- data/lib/startback/caching/entity_cache.rb +0 -157
- data/lib/startback/caching/no_store.rb +0 -28
- data/lib/startback/caching/store.rb +0 -34
- data/lib/startback/context/h_factory.rb +0 -43
- data/lib/startback/context/middleware.rb +0 -53
- data/lib/startback/context.rb +0 -122
- data/lib/startback/errors.rb +0 -197
- data/lib/startback/event/agent.rb +0 -84
- data/lib/startback/event/bus/bunny/async.rb +0 -162
- data/lib/startback/event/bus/bunny.rb +0 -1
- data/lib/startback/event/bus/memory/async.rb +0 -45
- data/lib/startback/event/bus/memory/sync.rb +0 -35
- data/lib/startback/event/bus/memory.rb +0 -2
- data/lib/startback/event/bus.rb +0 -100
- data/lib/startback/event/engine.rb +0 -94
- data/lib/startback/event/ext/context.rb +0 -5
- data/lib/startback/event/ext/operation.rb +0 -13
- data/lib/startback/event.rb +0 -47
- data/lib/startback/ext/date_time.rb +0 -9
- data/lib/startback/ext/time.rb +0 -9
- data/lib/startback/model.rb +0 -6
- data/lib/startback/operation/error_operation.rb +0 -19
- data/lib/startback/operation/multi_operation.rb +0 -28
- data/lib/startback/operation.rb +0 -78
- data/lib/startback/services.rb +0 -11
- data/lib/startback/support/data_object.rb +0 -71
- data/lib/startback/support/env.rb +0 -41
- data/lib/startback/support/fake_logger.rb +0 -18
- data/lib/startback/support/hooks.rb +0 -48
- data/lib/startback/support/log_formatter.rb +0 -34
- data/lib/startback/support/logger.rb +0 -34
- data/lib/startback/support/operation_runner.rb +0 -150
- data/lib/startback/support/robustness.rb +0 -157
- data/lib/startback/support/transaction_manager.rb +0 -25
- data/lib/startback/support/transaction_policy.rb +0 -33
- data/lib/startback/support/world.rb +0 -54
- data/lib/startback/support.rb +0 -26
- data/lib/startback/version.rb +0 -8
- data/lib/startback/web/api.rb +0 -99
- data/lib/startback/web/auto_caching.rb +0 -85
- data/lib/startback/web/catch_all.rb +0 -52
- data/lib/startback/web/cors_headers.rb +0 -80
- data/lib/startback/web/health_check.rb +0 -49
- data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
- data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
- data/lib/startback/web/magic_assets.rb +0 -98
- data/lib/startback/web/middleware.rb +0 -13
- data/lib/startback/web/prometheus.rb +0 -16
- data/lib/startback/web/shield.rb +0 -58
- data/lib/startback.rb +0 -43
- data/spec/unit/audit/test_prometheus.rb +0 -72
- data/spec/unit/audit/test_trailer.rb +0 -105
- data/spec/unit/caching/test_entity_cache.rb +0 -136
- data/spec/unit/context/test_abstraction_factory.rb +0 -64
- data/spec/unit/context/test_dup.rb +0 -42
- data/spec/unit/context/test_fork.rb +0 -37
- data/spec/unit/context/test_h_factory.rb +0 -31
- data/spec/unit/context/test_middleware.rb +0 -45
- data/spec/unit/context/test_with_world.rb +0 -20
- data/spec/unit/context/test_world.rb +0 -17
- data/spec/unit/event/bus/memory/test_async.rb +0 -43
- data/spec/unit/event/bus/memory/test_sync.rb +0 -43
- data/spec/unit/support/hooks/test_after_hook.rb +0 -54
- data/spec/unit/support/hooks/test_before_hook.rb +0 -54
- data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
- data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
- data/spec/unit/support/test_data_object.rb +0 -156
- data/spec/unit/support/test_env.rb +0 -75
- data/spec/unit/support/test_robusteness.rb +0 -229
- data/spec/unit/support/test_transaction_manager.rb +0 -64
- data/spec/unit/support/test_world.rb +0 -72
- data/spec/unit/test_event.rb +0 -62
- data/spec/unit/test_operation.rb +0 -55
- data/spec/unit/test_support.rb +0 -40
- data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
- data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
- data/spec/unit/web/fixtures/assets/index.es6 +0 -1
- data/spec/unit/web/test_api.rb +0 -82
- data/spec/unit/web/test_auto_caching.rb +0 -81
- data/spec/unit/web/test_catch_all.rb +0 -77
- data/spec/unit/web/test_cors_headers.rb +0 -88
- data/spec/unit/web/test_healthcheck.rb +0 -59
- data/spec/unit/web/test_magic_assets.rb +0 -82
@@ -1,157 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Caching
|
3
|
-
#
|
4
|
-
# A overriable caching abstraction aiming at making Entity-based caching easy.
|
5
|
-
#
|
6
|
-
# This class MUST be overriden:
|
7
|
-
#
|
8
|
-
# * the `load_entity` protected method MUST be implemented to load data from
|
9
|
-
# a primary & context unaware key.
|
10
|
-
#
|
11
|
-
# * the `primary_key` protected method MAY be implemented to convert candidate
|
12
|
-
# keys (received from ultimate callers) to primary keys. The method is also
|
13
|
-
# a good place to check and/or log the keys actually used by callers.
|
14
|
-
#
|
15
|
-
# * the `context_free_key` protected method MAY be overriden to provide
|
16
|
-
# domain unrelated caching keys from primary keys, e.g. by encoding the
|
17
|
-
# context into the caching key itself, if needed.
|
18
|
-
#
|
19
|
-
# * the `valid?` protected method MAY be overriden to check validity of data
|
20
|
-
# extracted from the cache and force a refresh even if found.
|
21
|
-
#
|
22
|
-
# An EntityCache takes an actual store at construction. The object must meet the
|
23
|
-
# specification writtern in Store. The 'cache' ruby gem can be used in practice.
|
24
|
-
#
|
25
|
-
# Cache hits, outdated and miss are logged in debug, info, and info severity.
|
26
|
-
# The `cache_hit`, `cache_outdated`, `cache_miss` protected methods MAY be
|
27
|
-
# overriden to change that behavior.
|
28
|
-
#
|
29
|
-
class EntityCache
|
30
|
-
include Support::Robustness
|
31
|
-
|
32
|
-
class << self
|
33
|
-
|
34
|
-
# Default time to live, in seconds
|
35
|
-
attr_writer :default_ttl
|
36
|
-
|
37
|
-
def default_ttl
|
38
|
-
@default_ttl || (superclass.respond_to?(:default_ttl, true) && superclass.default_ttl) || 3600
|
39
|
-
end
|
40
|
-
|
41
|
-
end # class DSL
|
42
|
-
|
43
|
-
def initialize(store, context = nil)
|
44
|
-
@store = store
|
45
|
-
@context = context
|
46
|
-
end
|
47
|
-
attr_reader :store, :context
|
48
|
-
|
49
|
-
# Returns the entity corresponding to a given key.
|
50
|
-
#
|
51
|
-
# If the entity is not in cache, loads it and puts it in cache using
|
52
|
-
# the caching options passed as second parameter.
|
53
|
-
def get(candidate_key, caching_options = default_caching_options)
|
54
|
-
pkey = primary_key(candidate_key)
|
55
|
-
cache_key = encode_key(context_free_key(pkey))
|
56
|
-
if store.exist?(cache_key)
|
57
|
-
cached = store.get(cache_key)
|
58
|
-
if valid?(pkey, cached)
|
59
|
-
cache_hit(pkey, cached)
|
60
|
-
return cached
|
61
|
-
else
|
62
|
-
cache_outdated(pkey, cached)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
cache_miss(pkey)
|
66
|
-
load_entity(pkey).tap{|to_cache|
|
67
|
-
store.set(cache_key, to_cache, caching_options)
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
# Invalidates the cache under a given key.
|
72
|
-
def invalidate(candidate_key)
|
73
|
-
pkey = primary_key(candidate_key)
|
74
|
-
cache_key = encode_key(context_free_key(pkey))
|
75
|
-
store.delete(cache_key)
|
76
|
-
end
|
77
|
-
|
78
|
-
protected
|
79
|
-
|
80
|
-
def cache_hit(pkey, cached)
|
81
|
-
log(:debug, self, "cache_hit", context, op_data: pkey)
|
82
|
-
end
|
83
|
-
|
84
|
-
def cache_outdated(pkey, cached)
|
85
|
-
log(:info, self, "cache_outdated", context, op_data: pkey)
|
86
|
-
end
|
87
|
-
|
88
|
-
def cache_miss(pkey)
|
89
|
-
log(:info, self, "cache_miss", context, op_data: pkey)
|
90
|
-
end
|
91
|
-
|
92
|
-
def default_caching_options
|
93
|
-
{ ttl: self.class.default_ttl }
|
94
|
-
end
|
95
|
-
|
96
|
-
# Converts a candidate key to a primary key, so as to prevent
|
97
|
-
# cache duplicates if callers are allowed to request an entity
|
98
|
-
# through various keys.
|
99
|
-
#
|
100
|
-
# The default implementation returns the candidate key and MAY
|
101
|
-
# be overriden.
|
102
|
-
def primary_key(candidate_key)
|
103
|
-
candidate_key
|
104
|
-
end
|
105
|
-
|
106
|
-
# Encodes a context free key to an actual cache key.
|
107
|
-
#
|
108
|
-
# Default implementation uses JSON.fast_generate but MAY be
|
109
|
-
# overriden.
|
110
|
-
def encode_key(context_free_key)
|
111
|
-
JSON.fast_generate(context_free_key)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Returns whether `cached` entity seems fresh enough to
|
115
|
-
# be returned as a cache hit.
|
116
|
-
#
|
117
|
-
# This method provides a way to check freshness using, e.g.
|
118
|
-
# `updated_at` or `etag` kind of entity fields. The default
|
119
|
-
# implementation returns true and MAY be overriden.
|
120
|
-
def valid?(primary_key, cached)
|
121
|
-
true
|
122
|
-
end
|
123
|
-
|
124
|
-
# Converts a primary_key to a context_free_key, using the
|
125
|
-
# context (instance variable) to encode the context itself
|
126
|
-
# into the actual cache key.
|
127
|
-
#
|
128
|
-
# The default implementation simply returns the primary key
|
129
|
-
# and MAY be overriden.
|
130
|
-
def context_free_key(primary_key)
|
131
|
-
full_key(primary_key)
|
132
|
-
end
|
133
|
-
|
134
|
-
# Deprecated, will be removed in 0.6.0. Use context_free_key
|
135
|
-
# instead.
|
136
|
-
def full_key(primary_key)
|
137
|
-
primary_key
|
138
|
-
end
|
139
|
-
|
140
|
-
# Actually loads the entity using the given primary key, and
|
141
|
-
# possibly the cache context.
|
142
|
-
#
|
143
|
-
# This method MUST be implemented and raises a NotImplementedError
|
144
|
-
# by default.
|
145
|
-
def load_entity(primary_key)
|
146
|
-
load_raw_data(primary_key)
|
147
|
-
end
|
148
|
-
|
149
|
-
# Deprecated, will be removed in 0.6.0. Use load_entity
|
150
|
-
# instead.
|
151
|
-
def load_raw_data(*args, &bl)
|
152
|
-
raise NotImplementedError, "#{self.class.name}#load_entity"
|
153
|
-
end
|
154
|
-
|
155
|
-
end # class EntityCache
|
156
|
-
end # module Caching
|
157
|
-
end # module Startback
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Caching
|
3
|
-
#
|
4
|
-
# Caching store implementation that caches nothing at all.
|
5
|
-
#
|
6
|
-
class NoStore
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
end
|
10
|
-
|
11
|
-
def exist?(key)
|
12
|
-
false
|
13
|
-
end
|
14
|
-
|
15
|
-
def get(key)
|
16
|
-
nil
|
17
|
-
end
|
18
|
-
|
19
|
-
def set(key, value, ttl)
|
20
|
-
value
|
21
|
-
end
|
22
|
-
|
23
|
-
def delete(key)
|
24
|
-
end
|
25
|
-
|
26
|
-
end # class NoStore
|
27
|
-
end # module Caching
|
28
|
-
end # module Startback
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Caching
|
3
|
-
#
|
4
|
-
# Caching store specification & dummy implementation.
|
5
|
-
#
|
6
|
-
# This class should not be used in real project, as it implements
|
7
|
-
# See the 'cache' gem that provides conforming implementations.
|
8
|
-
#
|
9
|
-
class Store
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@saved = {}
|
13
|
-
end
|
14
|
-
attr_reader :saved
|
15
|
-
|
16
|
-
def exist?(key)
|
17
|
-
saved.has_key?(key)
|
18
|
-
end
|
19
|
-
|
20
|
-
def get(key)
|
21
|
-
saved[key]
|
22
|
-
end
|
23
|
-
|
24
|
-
def set(key, value, ttl)
|
25
|
-
saved[key] = value
|
26
|
-
end
|
27
|
-
|
28
|
-
def delete(key)
|
29
|
-
saved.delete(key)
|
30
|
-
end
|
31
|
-
|
32
|
-
end # class Store
|
33
|
-
end # module Caching
|
34
|
-
end # module Startback
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
class Context
|
3
|
-
module HFactory
|
4
|
-
|
5
|
-
def h(hash)
|
6
|
-
h_factor!(self.new, hash)
|
7
|
-
end
|
8
|
-
|
9
|
-
def h_factor!(context, hash)
|
10
|
-
h_factories.each do |f|
|
11
|
-
f.call(context, hash)
|
12
|
-
end
|
13
|
-
context
|
14
|
-
end
|
15
|
-
|
16
|
-
def h_factories
|
17
|
-
@h_factories ||= []
|
18
|
-
end
|
19
|
-
|
20
|
-
def h_factory(&factory)
|
21
|
-
h_factories << factory
|
22
|
-
end
|
23
|
-
|
24
|
-
###
|
25
|
-
|
26
|
-
def h_dump!(context, hash = {})
|
27
|
-
h_dumpers.each do |d|
|
28
|
-
context.instance_exec(hash, &d)
|
29
|
-
end
|
30
|
-
hash
|
31
|
-
end
|
32
|
-
|
33
|
-
def h_dumpers
|
34
|
-
@h_dumpers ||= []
|
35
|
-
end
|
36
|
-
|
37
|
-
def h_dump(&dumper)
|
38
|
-
h_dumpers << dumper
|
39
|
-
end
|
40
|
-
|
41
|
-
end # module HFactory
|
42
|
-
end # class Context
|
43
|
-
end # module Startback
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
class Context
|
3
|
-
#
|
4
|
-
# Rack middleware that installs a particular context instance
|
5
|
-
# on the Rack environment.
|
6
|
-
#
|
7
|
-
# Examples:
|
8
|
-
#
|
9
|
-
# # Use the default context class
|
10
|
-
# Rack::Builder.new do
|
11
|
-
# use Startback::Context::Middleware
|
12
|
-
#
|
13
|
-
# run ->(env){
|
14
|
-
# ctx = env[Startback::Context::Middleware::RACK_ENV_KEY]
|
15
|
-
# ctx.is_a?(Startback::Context) # => true
|
16
|
-
# }
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# # Use a user defined context class
|
20
|
-
# Rack::Builder.new do
|
21
|
-
# use Startback::Context::Middleware, MyContextClass.new
|
22
|
-
#
|
23
|
-
# run ->(env){
|
24
|
-
# ctx = env[Startback::Context::Middleware::RACK_ENV_KEY]
|
25
|
-
# ctx.is_a?(MyContextClass) # => true (your subclass)
|
26
|
-
# ctx.is_a?(Startback::Context) # => true (required!)
|
27
|
-
# }
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
class Middleware
|
31
|
-
|
32
|
-
RACK_ENV_KEY = 'SAMBACK_CONTEXT'
|
33
|
-
|
34
|
-
def initialize(app, context = Context.new)
|
35
|
-
@app = app
|
36
|
-
@context = context
|
37
|
-
end
|
38
|
-
attr_reader :context
|
39
|
-
|
40
|
-
def call(env)
|
41
|
-
env[RACK_ENV_KEY] ||= context.dup.tap{|c|
|
42
|
-
c.original_rack_env = env.dup
|
43
|
-
}
|
44
|
-
@app.call(env)
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.context(env)
|
48
|
-
env[RACK_ENV_KEY]
|
49
|
-
end
|
50
|
-
|
51
|
-
end # class Middleware
|
52
|
-
end # class Context
|
53
|
-
end # module Startback
|
data/lib/startback/context.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
#
|
3
|
-
# Defines an execution context for Startback applications, and provides
|
4
|
-
# a cached factory for related abstractions (see `factor`), and an
|
5
|
-
# extensible world, statically and dynamically.
|
6
|
-
#
|
7
|
-
# In web application, an instance of a context can be set on the Rack
|
8
|
-
# environment, using Context::Middleware.
|
9
|
-
#
|
10
|
-
# This class SHOULD be subclassed for application required extensions
|
11
|
-
# to prevent touching the global Startback state itself.
|
12
|
-
#
|
13
|
-
# Also, for event handling in distributed architectures, a Context should
|
14
|
-
# be dumpable and reloadable to JSON. An `h` information contract if provided
|
15
|
-
# for that. Subclasses may contribute to the dumping and reloading process
|
16
|
-
# through the `h_dump` and `h_factory` methods
|
17
|
-
#
|
18
|
-
# module MyApp
|
19
|
-
# class Context < Startback::Context
|
20
|
-
#
|
21
|
-
# attr_accessor :foo
|
22
|
-
#
|
23
|
-
# h_dump do |h|
|
24
|
-
# h.merge!("foo" => foo)
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# h_factor do |c,h|
|
28
|
-
# c.foo = h["foo"]
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
class Context
|
35
|
-
attr_accessor :original_rack_env
|
36
|
-
|
37
|
-
# An error handler can be provided on the Context class. The latter
|
38
|
-
# MUST expose an API similar to ruby's Logger class. It can be a logger
|
39
|
-
# instance, simply.
|
40
|
-
#
|
41
|
-
# Fatal errors catched by Web::CatchAll are sent on `error_handler#fatal`
|
42
|
-
#
|
43
|
-
# Deprecated, use the logger below instead.
|
44
|
-
attr_accessor :error_handler
|
45
|
-
|
46
|
-
# A logger can be provided on the context, and will be used for everything
|
47
|
-
# related to logging, audit trailing and robustness. The logger receives
|
48
|
-
# object following the log & trail conventions of Startback, and must
|
49
|
-
# convert them to wathever log format is necessary.
|
50
|
-
attr_accessor :logger
|
51
|
-
|
52
|
-
require_relative 'context/h_factory'
|
53
|
-
extend(Context::HFactory)
|
54
|
-
|
55
|
-
def initialize
|
56
|
-
super
|
57
|
-
yield(self) if block_given?
|
58
|
-
end
|
59
|
-
|
60
|
-
attr_writer :_world
|
61
|
-
protected :_world=
|
62
|
-
|
63
|
-
def self.world(who, &block)
|
64
|
-
@_world ||= Support::World.new
|
65
|
-
@_world = @_world.factory(who, &block)
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.factor_world(context)
|
69
|
-
@_world ||= Support::World.new
|
70
|
-
@_world.with_scope(context)
|
71
|
-
end
|
72
|
-
|
73
|
-
def world
|
74
|
-
@_world ||= self.class.factor_world(self)
|
75
|
-
end
|
76
|
-
|
77
|
-
def with_world(world)
|
78
|
-
dup do |ctx|
|
79
|
-
ctx._world = self.world.with(world)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Factors an instance of `clazz`, which must be a Context-related
|
84
|
-
# abstraction (i.e. its constructor takes the context as last parameters).
|
85
|
-
#
|
86
|
-
# Factored abstractions are cached for a given context & arguments.
|
87
|
-
def factor(clazz, *args)
|
88
|
-
@factored ||= {}
|
89
|
-
key = args.empty? ? clazz : [clazz] + args
|
90
|
-
@factored[key] ||= clazz.new(*(args << self))
|
91
|
-
end
|
92
|
-
|
93
|
-
def clean_factored!
|
94
|
-
@factored = {}
|
95
|
-
end
|
96
|
-
private :clean_factored!
|
97
|
-
|
98
|
-
def to_h
|
99
|
-
self.class.h_dump!(self)
|
100
|
-
end
|
101
|
-
|
102
|
-
def to_json(*args, &bl)
|
103
|
-
to_h.to_json(*args, &bl)
|
104
|
-
end
|
105
|
-
|
106
|
-
def fork(h = nil)
|
107
|
-
dup.tap{|duped|
|
108
|
-
self.class.h_factor!(duped, h) if h
|
109
|
-
yield(duped) if block_given?
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
def dup
|
114
|
-
super.tap{|c|
|
115
|
-
c.send(:clean_factored!)
|
116
|
-
yield(c) if block_given?
|
117
|
-
}
|
118
|
-
end
|
119
|
-
|
120
|
-
end # class Context
|
121
|
-
end # module Startback
|
122
|
-
require_relative 'context/middleware'
|
data/lib/startback/errors.rb
DELETED
@@ -1,197 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Errors
|
3
|
-
|
4
|
-
class Error < StandardError
|
5
|
-
def initialize(message = nil, causes = nil)
|
6
|
-
super(message)
|
7
|
-
@causes = Array(causes)
|
8
|
-
end
|
9
|
-
attr_reader :causes
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def status(code = nil)
|
13
|
-
if code.nil?
|
14
|
-
@code || (superclass.respond_to?(:status) ? superclass.status : 500)
|
15
|
-
else
|
16
|
-
@code = code || @code
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def keep_error(keep = nil)
|
21
|
-
@keep_error = keep unless keep.nil?
|
22
|
-
@keep_error
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def message
|
27
|
-
msg = super
|
28
|
-
return msg unless msg == self.class.name
|
29
|
-
parts = self.class.name.split('::').last.gsub(/[A-Z]/){|x|
|
30
|
-
" #{x.downcase}"
|
31
|
-
}.strip.split(" ")
|
32
|
-
parts = parts[0...-1] unless self.class.keep_error
|
33
|
-
parts.join(" ").capitalize
|
34
|
-
end
|
35
|
-
|
36
|
-
def has_causes?
|
37
|
-
causes && !causes.empty?
|
38
|
-
end
|
39
|
-
|
40
|
-
def cause
|
41
|
-
causes&.first
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class BadRequestError < Error
|
46
|
-
status 400
|
47
|
-
end
|
48
|
-
|
49
|
-
class UnauthorizedError < BadRequestError
|
50
|
-
status 401
|
51
|
-
end
|
52
|
-
|
53
|
-
class ForbiddenError < BadRequestError
|
54
|
-
status 403
|
55
|
-
end
|
56
|
-
|
57
|
-
class NotFoundError < BadRequestError
|
58
|
-
status 404
|
59
|
-
end
|
60
|
-
|
61
|
-
class MethodNotAllowedError < BadRequestError
|
62
|
-
status 405
|
63
|
-
end
|
64
|
-
|
65
|
-
class NotAcceptableError < BadRequestError
|
66
|
-
status 406
|
67
|
-
end
|
68
|
-
|
69
|
-
class ConflictError < BadRequestError
|
70
|
-
status 409
|
71
|
-
end
|
72
|
-
|
73
|
-
class GoneError < BadRequestError
|
74
|
-
status 410
|
75
|
-
end
|
76
|
-
|
77
|
-
class PreconditionFailedError < BadRequestError
|
78
|
-
status 412
|
79
|
-
end
|
80
|
-
|
81
|
-
class UnsupportedMediaTypeError < BadRequestError
|
82
|
-
status 415
|
83
|
-
end
|
84
|
-
|
85
|
-
class ExpectationFailedError < BadRequestError
|
86
|
-
status 417
|
87
|
-
end
|
88
|
-
|
89
|
-
class LockedError < BadRequestError
|
90
|
-
status 423
|
91
|
-
end
|
92
|
-
|
93
|
-
class PreconditionRequiredError < BadRequestError
|
94
|
-
status 428
|
95
|
-
end
|
96
|
-
|
97
|
-
class InternalServerError < Error
|
98
|
-
status 500
|
99
|
-
keep_error(true)
|
100
|
-
end
|
101
|
-
|
102
|
-
class NotImplementedError < InternalServerError
|
103
|
-
status 501
|
104
|
-
end
|
105
|
-
|
106
|
-
### Helper methods
|
107
|
-
|
108
|
-
def bad_request_error!(msg = nil)
|
109
|
-
raise Startback::Errors::BadRequestError, msg
|
110
|
-
end
|
111
|
-
module_function :bad_request_error!
|
112
|
-
|
113
|
-
def unauthorized_error!(msg = nil)
|
114
|
-
raise Startback::Errors::UnauthorizedError, msg
|
115
|
-
end
|
116
|
-
module_function :unauthorized_error!
|
117
|
-
|
118
|
-
def forbidden_error!(msg = nil)
|
119
|
-
raise Startback::Errors::ForbiddenError, msg
|
120
|
-
end
|
121
|
-
module_function :forbidden_error!
|
122
|
-
|
123
|
-
def not_found_error!(msg = nil)
|
124
|
-
raise Startback::Errors::NotFoundError, "#{msg} not found"
|
125
|
-
end
|
126
|
-
module_function :not_found_error!
|
127
|
-
|
128
|
-
def method_not_allowed_error!(msg = nil)
|
129
|
-
raise Startback::Errors::MethodNotAllowedError, msg
|
130
|
-
end
|
131
|
-
module_function :method_not_allowed_error!
|
132
|
-
|
133
|
-
def not_acceptable_error!(msg = nil)
|
134
|
-
raise Startback::Errors::NotAcceptableError, msg
|
135
|
-
end
|
136
|
-
module_function :not_acceptable_error!
|
137
|
-
|
138
|
-
def conflict_error!(msg = nil)
|
139
|
-
raise Startback::Errors::ConflictError, msg
|
140
|
-
end
|
141
|
-
module_function :conflict_error!
|
142
|
-
|
143
|
-
def gone_error!(msg = nil)
|
144
|
-
raise Startback::Errors::GoneError, msg
|
145
|
-
end
|
146
|
-
module_function :gone_error!
|
147
|
-
|
148
|
-
def precondition_failed_error!(msg = nil)
|
149
|
-
raise Startback::Errors::PreconditionFailedError, msg
|
150
|
-
end
|
151
|
-
module_function :precondition_failed_error!
|
152
|
-
|
153
|
-
def unsupported_media_type_error!(media)
|
154
|
-
raise Startback::Errors::UnsupportedMediaTypeError, "Unable to use `#{media}` as input data"
|
155
|
-
end
|
156
|
-
module_function :unsupported_media_type_error!
|
157
|
-
|
158
|
-
def expectation_failed_error!(msg = nil)
|
159
|
-
raise Startback::Errors::ExpectationFailedError, msg
|
160
|
-
end
|
161
|
-
module_function :expectation_failed_error!
|
162
|
-
|
163
|
-
def locked_error!(msg = nil)
|
164
|
-
raise Startback::Errors::LockedError, msg
|
165
|
-
end
|
166
|
-
module_function :locked_error!
|
167
|
-
|
168
|
-
def precondition_required_error!(msg = nil)
|
169
|
-
raise Startback::Errors::PreconditionRequiredError, msg
|
170
|
-
end
|
171
|
-
module_function :precondition_required_error!
|
172
|
-
|
173
|
-
def internal_server_error!(msg = nil)
|
174
|
-
raise Startback::Errors::InternalServerError, msg
|
175
|
-
end
|
176
|
-
module_function :internal_server_error!
|
177
|
-
|
178
|
-
def not_implemented_error!(msg = nil)
|
179
|
-
raise Startback::Errors::NotImplementedError, msg
|
180
|
-
end
|
181
|
-
module_function :not_implemented_error!
|
182
|
-
|
183
|
-
# Aliases
|
184
|
-
|
185
|
-
def user_error!(msg = nil)
|
186
|
-
raise Startback::Errors::BadRequestError, msg
|
187
|
-
end
|
188
|
-
module_function :user_error!
|
189
|
-
|
190
|
-
def server_error!(msg = nil)
|
191
|
-
raise Startback::Errors::InternalServerError, msg
|
192
|
-
end
|
193
|
-
module_function :server_error!
|
194
|
-
|
195
|
-
end # module Errors
|
196
|
-
include Errors
|
197
|
-
end # module Startback
|