diff --git a/lib/skyfall/firehose/account_message.rb b/lib/skyfall/firehose/account_message.rb index f020b1f..d0ef968 100644 --- a/lib/skyfall/firehose/account_message.rb +++ b/lib/skyfall/firehose/account_message.rb @@ -21,7 +21,7 @@ module Skyfall # def initialize(type_object, data_object) super - raise DecodeError.new("Missing event details") if @data_object['active'].nil? + check_if_not_nil :seq, :did, :time, :active @active = @data_object['active'] @status = @data_object['status']&.to_sym diff --git a/lib/skyfall/firehose/commit_message.rb b/lib/skyfall/firehose/commit_message.rb index e56d960..f41da86 100644 --- a/lib/skyfall/firehose/commit_message.rb +++ b/lib/skyfall/firehose/commit_message.rb @@ -15,9 +15,20 @@ module Skyfall class Firehose::CommitMessage < Firehose::Message + # + # @private + # @param type_object [Hash] first decoded CBOR frame with metadata + # @param data_object [Hash] second decoded CBOR frame with payload + # @raise [DecodeError] if the message doesn't include required data + # + def initialize(type_object, data_object) + super + check_if_not_nil :seq, :repo, :commit, :blocks, :ops, :time + end + # @return [CID] CID (Content Identifier) of the commit def commit - @commit ||= @data_object['commit'] && CID.from_cbor_tag(@data_object['commit']) + @commit ||= CID.from_cbor_tag(@data_object['commit']) end # @return [Skyfall::CarArchive] commit data in the form of a parsed CAR archive diff --git a/lib/skyfall/firehose/identity_message.rb b/lib/skyfall/firehose/identity_message.rb index 7c4b5f9..78e93d5 100644 --- a/lib/skyfall/firehose/identity_message.rb +++ b/lib/skyfall/firehose/identity_message.rb @@ -15,9 +15,20 @@ module Skyfall class Firehose::IdentityMessage < Firehose::Message - # @return [String, nil] current handle assigned to the DID - def handle - @data_object['handle'] + # + # @private + # @param type_object [Hash] first decoded CBOR frame with metadata + # @param data_object [Hash] second decoded CBOR frame with payload + # @raise [DecodeError] if the message doesn't include required data + # + def initialize(type_object, data_object) + super + check_if_not_nil :seq, :did, :time + + @handle = @data_object['handle'] end + + # @return [String, nil] current handle assigned to the DID + attr_reader :handle end end diff --git a/lib/skyfall/firehose/info_message.rb b/lib/skyfall/firehose/info_message.rb index a2d5e3e..4442b53 100644 --- a/lib/skyfall/firehose/info_message.rb +++ b/lib/skyfall/firehose/info_message.rb @@ -30,9 +30,11 @@ module Skyfall # @private # @param type_object [Hash] first decoded CBOR frame with metadata # @param data_object [Hash] second decoded CBOR frame with payload + # @raise [DecodeError] if the message doesn't include required data # def initialize(type_object, data_object) super + check_if_not_nil :name @name = @data_object['name'] @message = @data_object['message'] diff --git a/lib/skyfall/firehose/labels_message.rb b/lib/skyfall/firehose/labels_message.rb index c72a91f..374849f 100644 --- a/lib/skyfall/firehose/labels_message.rb +++ b/lib/skyfall/firehose/labels_message.rb @@ -23,7 +23,7 @@ module Skyfall # def initialize(type_object, data_object) super - raise DecodeError.new("Missing event details") unless @data_object['labels'].is_a?(Array) + check_if_not_nil :seq, :labels @labels = @data_object['labels'].map { |x| Label.new(x) } end diff --git a/lib/skyfall/firehose/message.rb b/lib/skyfall/firehose/message.rb index 672e291..b13f6f3 100644 --- a/lib/skyfall/firehose/message.rb +++ b/lib/skyfall/firehose/message.rb @@ -145,6 +145,15 @@ module Skyfall instance_variables - [:@type_object, :@data_object, :@blocks] end + # Checks if all required fields are set in the data object. + # @param fields [Array] list of fields to check + # @raise [DecodeError] if any of the fields is nil or not set + def check_if_not_nil(*fields) + missing = fields.select { |f| @data_object[f.to_s].nil? } + + raise DecodeError.new("Missing event details (#{missing.map(&:to_s).join(', ')})") if missing.length > 0 + end + private @@ -163,11 +172,13 @@ module Skyfall raise SubscriptionError.new(data['error'], data['message']) end - raise DecodeError.new("Invalid object type: #{type}") unless type.is_a?(Hash) - raise UnsupportedError.new("Unexpected CBOR object: #{type}") unless type['op'] == 1 - raise DecodeError.new("Missing data: #{type} #{objects.inspect}") unless type['op'] && type['t'] - raise DecodeError.new("Invalid message type: #{type['t']}") unless type['t'].start_with?('#') - raise DecodeError.new("Invalid object type: #{data}") unless data.is_a?(Hash) + raise DecodeError.new("Invalid object type: #{type.inspect}") unless type.is_a?(Hash) + raise DecodeError.new("Missing data: #{type.inspect}") unless type['op'] && type['t'] + raise DecodeError.new("Invalid object type: #{type['op'].inspect}") unless type['op'].is_a?(Integer) + raise DecodeError.new("Invalid object type: #{type['t'].inspect}") unless type['t'].is_a?(String) + raise DecodeError.new("Invalid message type: #{type['t'].inspect}") unless type['t'].start_with?('#') + raise UnsupportedError.new("Unsupported version: #{type['op']}") unless type['op'] == 1 + raise DecodeError.new("Invalid object type: #{data.inspect}") unless data.is_a?(Hash) [type, data] end diff --git a/lib/skyfall/jetstream/account_message.rb b/lib/skyfall/jetstream/account_message.rb index a7803ca..85008c9 100644 --- a/lib/skyfall/jetstream/account_message.rb +++ b/lib/skyfall/jetstream/account_message.rb @@ -19,7 +19,7 @@ module Skyfall # @raise [DecodeError] if the message doesn't include required data # def initialize(json) - raise DecodeError.new("Missing event details") if json['account'].nil? + raise DecodeError.new("Missing event details (account)") if json['account'].nil? || json['account']['active'].nil? super end diff --git a/lib/skyfall/jetstream/commit_message.rb b/lib/skyfall/jetstream/commit_message.rb index 9ba6bea..fe5c5d7 100644 --- a/lib/skyfall/jetstream/commit_message.rb +++ b/lib/skyfall/jetstream/commit_message.rb @@ -17,7 +17,10 @@ module Skyfall # @raise [DecodeError] if the message doesn't include required data # def initialize(json) - raise DecodeError.new("Missing event details") if json['commit'].nil? + raise DecodeError.new("Missing event details (commit)") if json['commit'].nil? + + %w(collection rkey operation).each { |f| raise DecodeError.new("Missing event details (#{f})") if json['commit'][f].nil? } + super end diff --git a/lib/skyfall/jetstream/identity_message.rb b/lib/skyfall/jetstream/identity_message.rb index 1ba5e41..3f527f0 100644 --- a/lib/skyfall/jetstream/identity_message.rb +++ b/lib/skyfall/jetstream/identity_message.rb @@ -21,7 +21,7 @@ module Skyfall # @raise [DecodeError] if the message doesn't include required data # def initialize(json) - raise DecodeError.new("Missing event details") if json['identity'].nil? + raise DecodeError.new("Missing event details (identity)") if json['identity'].nil? super end diff --git a/lib/skyfall/jetstream/message.rb b/lib/skyfall/jetstream/message.rb index c67229a..81a15c0 100644 --- a/lib/skyfall/jetstream/message.rb +++ b/lib/skyfall/jetstream/message.rb @@ -72,8 +72,11 @@ module Skyfall # # @param json [Hash] message JSON decoded from the websocket message + # @raise [DecodeError] if the message doesn't include required data # def initialize(json) + %w(kind did time_us).each { |f| raise DecodeError.new("Missing event details (#{f})") if json[f].nil? } + @json = json @type = @json['kind'].to_sym @did = @json['did'] @@ -122,7 +125,7 @@ module Skyfall # @return [Time] # def time - @time ||= @json['time_us'] && Time.at(@json['time_us'] / 1_000_000.0) + @time ||= Time.at(@time_us / 1_000_000.0) end end end