Skip to content

Commit

Permalink
Merge branch 'generate-error-codes'
Browse files Browse the repository at this point in the history
  • Loading branch information
mattheworiordan committed Nov 11, 2018
2 parents ccb4e17 + ea425be commit a48e4dc
Show file tree
Hide file tree
Showing 35 changed files with 625 additions and 266 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
sudo: false
env:
- RSPEC_RETRY=true PROTOCOL=json
- RSPEC_RETRY=true PROTOCOL=msgpack
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=6 PROTOCOL=json
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=6 PROTOCOL=msgpack
language: ruby
rvm:
- 1.9.3
- 2.0.0
- 2.1.10
- 2.2.0
- 2.3.6
- 2.4.1
script: bundle exec rspec
- 2.4.4
script: spec/run_parallel_tests
notifications:
slack:
secure: Xe8MwDcV2C8XLGk6O6Co31LpQiRSxsmS7Toy5vM7rHds5fnVRBNn5iX6Q5mXMdLOlnsMhjKLt7zl4fsBOZv+siQ+Us0omZSIYpXCYSCIj8nofReF0Lj8M4oa6lFSL5OuygO7PH+wLKTRxQURGZ6Pi1nHU+RE5izRmsewQHkhtY0=
32 changes: 32 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ begin
Rake::Task[:spec].invoke
end
end

desc 'Generate error code constants from ably-common: https://github.com/ably/ably-common/issues/32'
task :generate_error_codes do
errors_json_path = File.join(File.dirname(__FILE__), 'lib/submodules/ably-common/protocol/errors.json')
module_path = File.join(File.dirname(__FILE__), 'lib/ably/modules/exception_codes.rb')
max_length = 0

errors = JSON.parse(File.read(errors_json_path)).each_with_object({}) do |(key, val), hash|
hash[key] = val.split(/\s+/).map { |d| d.upcase.gsub(/[^a-zA-Z]+/, '') }.join('_')
end.each do |code, const_name|
max_length = [const_name.length, max_length].max
end.map do |code, const_name|
" #{const_name.ljust(max_length, ' ')} = #{code}"
end.join("\n")
module_content = <<-EOF
# This file is generated by running `rake :generate_error_codes`
# Do not manually modify this file
# Generated at: #{Time.now.utc}
#
module Ably
module Exceptions
module Codes
#{errors}
end
end
end
EOF
File.open(module_path, 'w') { |file| file.write module_content }

puts "Error code constants have been generated into #{module_path}"
puts "Warning: Search for any constants referenced in this library if their name has changed as a result of this constant generation!"
end
rescue LoadError
# RSpec not available
end
13 changes: 9 additions & 4 deletions ably.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'bundler', '~> 1.3'
spec.add_development_dependency 'rake', '~> 11.3'
spec.add_development_dependency 'redcarpet', '~> 3.3'
spec.add_development_dependency 'rspec', '~> 3.2.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
spec.add_development_dependency 'rspec-retry', '~> 0.4'
spec.add_development_dependency 'rspec', '~> 3.3.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
spec.add_development_dependency 'rspec-retry', '~> 0.6'
spec.add_development_dependency 'yard', '~> 0.9'
spec.add_development_dependency 'rspec-instafail', '~> 1.0'

if RUBY_VERSION.match(/^1/)
spec.add_development_dependency 'public_suffix', '~> 1.4.6' # Later versions do not support Ruby 1.9
spec.add_development_dependency 'webmock', '2.2'
spec.add_development_dependency 'parallel_tests', '~> 2.9.0'
else
spec.add_development_dependency 'webmock', '~> 2.2'
spec.add_development_dependency 'coveralls'
spec.add_development_dependency 'pry'
spec.add_development_dependency 'pry-byebug'
spec.add_development_dependency 'parallel_tests', '~> 2.22'
if !RUBY_VERSION.match(/^2\.[0123]/)
spec.add_development_dependency 'pry'
spec.add_development_dependency 'pry-byebug'
end
end
end
4 changes: 2 additions & 2 deletions lib/ably/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,15 @@ def request_token(token_params = {}, auth_options = {})
auth_callback.call(token_params)
end
rescue StandardError => err
raise Ably::Exceptions::AuthenticationFailed.new("auth_callback failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: 80019)
raise Ably::Exceptions::AuthenticationFailed.new("auth_callback failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: Ably::Exceptions::Codes::CONNECTION_NOT_ESTABLISHED_NO_TRANSPORT_HANDLE)
end
elsif auth_url = auth_options.delete(:auth_url)
begin
Timeout::timeout(client.auth_request_timeout) do
token_request_from_auth_url(auth_url, auth_options, token_params)
end
rescue StandardError => err
raise Ably::Exceptions::AuthenticationFailed.new("auth_url failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: 80019)
raise Ably::Exceptions::AuthenticationFailed.new("auth_url failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: Ably::Exceptions::Codes::CONNECTION_NOT_ESTABLISHED_NO_TRANSPORT_HANDLE)
end
else
create_token_request(token_params, auth_options)
Expand Down
8 changes: 6 additions & 2 deletions lib/ably/exceptions.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require 'ably/modules/exception_codes'

module Ably
module Exceptions
TOKEN_EXPIRED_CODE = 40140..40149
INVALID_CLIENT_ID = 40012

# Base Ably exception class that contains status and code values used by Ably
# Refer to https://github.com/ably/ably-common/blob/master/protocol/errors.json
Expand Down Expand Up @@ -37,6 +38,7 @@ def to_s
additional_info << "base exception: #{@base_exception.class}" if @base_exception
additional_info << "request_id: #{request_id}" if request_id
message << "(#{additional_info.join(', ')})"
message << "-> see https://help.ably.io/error/#{code} for help" if code
end
message.join(' ')
end
Expand All @@ -53,6 +55,8 @@ def as_json(*args)
# An invalid request was received by Ably
class InvalidRequest < BaseAblyException; end

class InvalidCredentials < BaseAblyException; end

# Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided
class UnauthorizedRequest < BaseAblyException; end

Expand Down Expand Up @@ -146,7 +150,7 @@ class UnsupportedDataType < BaseAblyException; end
class ChannelInactive < BaseAblyException; end

class IncompatibleClientId < BaseAblyException
def initialize(messages, status = 400, code = INVALID_CLIENT_ID, *args)
def initialize(messages, status = 400, code = Ably::Exceptions::Codes::INVALID_CLIENT_ID, *args)
super(message, status, code, *args)
end
end
Expand Down
6 changes: 4 additions & 2 deletions lib/ably/models/error_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def initialize(hash_object)
@hash_object = IdiomaticRubyWrapper(hash_object.clone.freeze)
end

%w(message code status_code).each do |attribute|
%w(message code href status_code).each do |attribute|
define_method attribute do
attributes[attribute.to_sym]
end
Expand All @@ -50,7 +50,9 @@ def attributes
end

def to_s
"<Error: #{message} (code: #{code}, http status: #{status})>"
error_href = href || (code ? "https://help.ably.io/error/#{code}" : '')
see_msg = " -> see #{error_href} for help" unless message.to_s.include?(error_href.to_s)
"<Error: #{message} (code: #{code}, http status: #{status})>#{see_msg}"
end
end
end
2 changes: 1 addition & 1 deletion lib/ably/modules/conversions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def ensure_supported_payload(payload)
payload.kind_of?(Array) ||
payload.nil?

raise Ably::Exceptions::UnsupportedDataType.new('Invalid data payload', 400, 40011)
raise Ably::Exceptions::UnsupportedDataType.new('Invalid data payload', 400, Ably::Exceptions::Codes::INVALID_MESSAGE_DATA_OR_ENCODING)
end
end
end
128 changes: 128 additions & 0 deletions lib/ably/modules/exception_codes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# This file is generated by running `rake :generate_error_codes`
# Do not manually modify this file
# Generated at: 2018-09-18 18:28:58 UTC
#
module Ably
module Exceptions
module Codes
NO_ERROR = 10000
BAD_REQUEST = 40000
INVALID_REQUEST_BODY = 40001
INVALID_PARAMETER_NAME = 40002
INVALID_PARAMETER_VALUE = 40003
INVALID_HEADER = 40004
INVALID_CREDENTIAL = 40005
INVALID_CONNECTION_ID = 40006
INVALID_MESSAGE_ID = 40007
INVALID_CONTENT_LENGTH = 40008
MAXIMUM_MESSAGE_LENGTH_EXCEEDED = 40009
INVALID_CHANNEL_NAME = 40010
STALE_RING_STATE = 40011
INVALID_CLIENT_ID = 40012
INVALID_MESSAGE_DATA_OR_ENCODING = 40013
RESOURCE_DISPOSED = 40014
INVALID_DEVICE_ID = 40015
BATCH_ERROR = 40020
INVALID_PUBLISH_REQUEST_UNSPECIFIED = 40030
INVALID_PUBLISH_REQUEST_INVALID_CLIENTSPECIFIED_ID = 40031
UNAUTHORIZED = 40100
INVALID_CREDENTIALS = 40101
INCOMPATIBLE_CREDENTIALS = 40102
INVALID_USE_OF_BASIC_AUTH_OVER_NONTLS_TRANSPORT = 40103
TIMESTAMP_NOT_CURRENT = 40104
NONCE_VALUE_REPLAYED = 40105
UNABLE_TO_OBTAIN_CREDENTIALS_FROM_GIVEN_PARAMETERS = 40106
ACCOUNT_DISABLED = 40110
ACCOUNT_RESTRICTED_CONNECTION_LIMITS_EXCEEDED = 40111
ACCOUNT_BLOCKED_MESSAGE_LIMITS_EXCEEDED = 40112
ACCOUNT_BLOCKED = 40113
ACCOUNT_RESTRICTED_CHANNEL_LIMITS_EXCEEDED = 40114
APPLICATION_DISABLED = 40120
KEY_ERROR_UNSPECIFIED = 40130
KEY_REVOKED = 40131
KEY_EXPIRED = 40132
KEY_DISABLED = 40133
TOKEN_ERROR_UNSPECIFIED = 40140
TOKEN_REVOKED = 40141
TOKEN_EXPIRED = 40142
TOKEN_UNRECOGNISED = 40143
INVALID_JWT_FORMAT = 40144
INVALID_TOKEN_FORMAT = 40145
CONNECTION_BLOCKED_LIMITS_EXCEEDED = 40150
OPERATION_NOT_PERMITTED_WITH_PROVIDED_CAPABILITY = 40160
ERROR_FROM_CLIENT_TOKEN_CALLBACK = 40170
FORBIDDEN = 40300
ACCOUNT_DOES_NOT_PERMIT_TLS_CONNECTION = 40310
OPERATION_REQUIRES_TLS_CONNECTION = 40311
APPLICATION_REQUIRES_AUTHENTICATION = 40320
UNABLE_TO_ACTIVATE_ACCOUNT_DUE_TO_PLACEMENT_CONSTRAINT_UNSPECIFIED = 40330
UNABLE_TO_ACTIVATE_ACCOUNT_DUE_TO_PLACEMENT_CONSTRAINT_INCOMPATIBLE_ENVIRONMENT = 40331
UNABLE_TO_ACTIVATE_ACCOUNT_DUE_TO_PLACEMENT_CONSTRAINT_INCOMPATIBLE_SITE = 40332
NOT_FOUND = 40400
METHOD_NOT_ALLOWED = 40500
RATE_LIMIT_EXCEEDED_NONFATAL_REQUEST_REJECTED_UNSPECIFIED = 42910
MAX_PERCONNECTION_PUBLISH_RATE_LIMIT_EXCEEDED_NONFATAL_UNABLE_TO_PUBLISH_MESSAGE = 42911
RATE_LIMIT_EXCEEDED_FATAL = 42920
MAX_PERCONNECTION_PUBLISH_RATE_LIMIT_EXCEEDED_FATAL_CLOSING_CONNECTION = 42921
INTERNAL_ERROR = 50000
INTERNAL_CHANNEL_ERROR = 50001
INTERNAL_CONNECTION_ERROR = 50002
TIMEOUT_ERROR = 50003
REQUEST_FAILED_DUE_TO_OVERLOADED_INSTANCE = 50004
REACTOR_OPERATION_FAILED = 70000
REACTOR_OPERATION_FAILED_POST_OPERATION_FAILED = 70001
REACTOR_OPERATION_FAILED_POST_OPERATION_RETURNED_UNEXPECTED_CODE = 70002
REACTOR_OPERATION_FAILED_MAXIMUM_NUMBER_OF_CONCURRENT_INFLIGHT_REQUESTS_EXCEEDED = 70003
EXCHANGE_ERROR_UNSPECIFIED = 71000
FORCED_REATTACHMENT_DUE_TO_PERMISSIONS_CHANGE = 71001
EXCHANGE_PUBLISHER_ERROR_UNSPECIFIED = 71100
NO_SUCH_PUBLISHER = 71101
PUBLISHER_NOT_ENABLED_AS_AN_EXCHANGE_PUBLISHER = 71102
EXCHANGE_PRODUCT_ERROR_UNSPECIFIED = 71200
NO_SUCH_PRODUCT = 71201
PRODUCT_DISABLED = 71202
NO_SUCH_CHANNEL_IN_THIS_PRODUCT = 71203
EXCHANGE_SUBSCRIPTION_ERROR_UNSPECIFIED = 71300
SUBSCRIPTION_DISABLED = 71301
REQUESTER_HAS_NO_SUBSCRIPTION_TO_THIS_PRODUCT = 71302
CONNECTION_FAILED = 80000
CONNECTION_FAILED_NO_COMPATIBLE_TRANSPORT = 80001
CONNECTION_SUSPENDED = 80002
DISCONNECTED = 80003
ALREADY_CONNECTED = 80004
INVALID_CONNECTION_ID_REMOTE_NOT_FOUND = 80005
UNABLE_TO_RECOVER_CONNECTION_MESSAGES_EXPIRED = 80006
UNABLE_TO_RECOVER_CONNECTION_MESSAGE_LIMIT_EXCEEDED = 80007
UNABLE_TO_RECOVER_CONNECTION_CONNECTION_EXPIRED = 80008
CONNECTION_NOT_ESTABLISHED_NO_TRANSPORT_HANDLE = 80009
INVALID_OPERATION_INVALID_TRANSPORT_HANDLE = 80010
UNABLE_TO_RECOVER_CONNECTION_INCOMPATIBLE_AUTH_PARAMS = 80011
UNABLE_TO_RECOVER_CONNECTION_INVALID_OR_UNSPECIFIED_CONNECTION_SERIAL = 80012
PROTOCOL_ERROR = 80013
CONNECTION_TIMED_OUT = 80014
INCOMPATIBLE_CONNECTION_PARAMETERS = 80015
OPERATION_ON_SUPERSEDED_TRANSPORT = 80016
CONNECTION_CLOSED = 80017
INVALID_CONNECTION_ID_INVALID_FORMAT = 80018
CLIENT_CONFIGURED_AUTHENTICATION_PROVIDER_REQUEST_FAILED = 80019
CONTINUITY_LOSS_DUE_TO_MAXIMUM_SUBSCRIBE_MESSAGE_RATE_EXCEEDED = 80020
CLIENT_RESTRICTION_NOT_SATISFIED = 80030
CHANNEL_OPERATION_FAILED = 90000
CHANNEL_OPERATION_FAILED_INVALID_CHANNEL_STATE = 90001
CHANNEL_OPERATION_FAILED_EPOCH_EXPIRED_OR_NEVER_EXISTED = 90002
UNABLE_TO_RECOVER_CHANNEL_MESSAGES_EXPIRED = 90003
UNABLE_TO_RECOVER_CHANNEL_MESSAGE_LIMIT_EXCEEDED = 90004
UNABLE_TO_RECOVER_CHANNEL_NO_MATCHING_EPOCH = 90005
UNABLE_TO_RECOVER_CHANNEL_UNBOUNDED_REQUEST = 90006
CHANNEL_OPERATION_FAILED_NO_RESPONSE_FROM_SERVER = 90007
MAXIMUM_NUMBER_OF_CHANNELS_PER_CONNECTION_EXCEEDED = 90010
UNABLE_TO_ENTER_PRESENCE_CHANNEL_NO_CLIENTID = 91000
UNABLE_TO_ENTER_PRESENCE_CHANNEL_INVALID_CHANNEL_STATE = 91001
UNABLE_TO_LEAVE_PRESENCE_CHANNEL_THAT_IS_NOT_ENTERED = 91002
UNABLE_TO_ENTER_PRESENCE_CHANNEL_MAXIMUM_MEMBER_LIMIT_EXCEEDED = 91003
UNABLE_TO_AUTOMATICALLY_REENTER_PRESENCE_CHANNEL = 91004
PRESENCE_STATE_IS_OUT_OF_SYNC = 91005
MEMBER_IMPLICITLY_LEFT_PRESENCE_CHANNEL_CONNECTION_CLOSED = 91100
end
end
end
2 changes: 1 addition & 1 deletion lib/ably/modules/state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def previous_state
# @return [Ably::Exceptions::InvalidStateChange]
def exception_for_state_change_to(state)
error_message = "#{self.class}: Unable to transition from #{current_state} => #{state}"
Ably::Exceptions::InvalidStateChange.new(error_message, nil, 90001)
Ably::Exceptions::InvalidStateChange.new(error_message, nil, Ably::Exceptions::Codes::CHANNEL_OPERATION_FAILED_INVALID_CHANNEL_STATE)
end

module ClassMethods
Expand Down
2 changes: 1 addition & 1 deletion lib/ably/realtime/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def auth_params(&success_callback)
# Use base exception if it exists carrying forward the status codes
deferrable.fail Ably::Exceptions::AuthenticationFailed.new(error.message, nil, nil, error)
else
deferrable.fail Ably::Exceptions::AuthenticationFailed.new(error.message, 500, 80019)
deferrable.fail Ably::Exceptions::AuthenticationFailed.new(error.message, 500, Ably::Exceptions::Codes::CLIENT_CONFIGURED_AUTHENTICATION_PROVIDER_REQUEST_FAILED)
end
end
async_wrap(success_callback, fail_callback) do
Expand Down
Loading

0 comments on commit a48e4dc

Please sign in to comment.