Module: AsyncapiCable::Diagnostics

Defined in:
lib/asyncapi_cable/diagnostics.rb

Overview

Explanations for validation failures whose cause is not what the failure says. Only the wording changes — a payload that fails still fails.

Constant Summary collapse

DOUBLE_ENCODED =
<<~TEXT.chomp
  The payload is a JSON string rather than an object. A broadcast site
  passing already-serialized JSON (`to_json`, or a renderer that returns a
  String) leaves ActionCable to encode it a second time, so the wire
  carries a JSON string literal and the client has to parse twice.
  Broadcast a Hash, or describe the string with `contentMediaType` and
  `contentSchema`.
TEXT

Class Method Summary collapse

Class Method Details

.hint_for(payload, errors) ⇒ Object

A String payload alone proves nothing: contentSchema describes an embedded representation on purpose, and such a message validates. This fires only when a schema wanted an object or array at the root and got a string that happens to parse as one — the signature of a payload serialized a layer too early.



23
24
25
26
27
28
# File 'lib/asyncapi_cable/diagnostics.rb', line 23

def hint_for(payload, errors)
  return nil unless serialized_container?(payload)
  return nil unless root_container_expected?(errors)

  DOUBLE_ENCODED
end

.root_container_expected?(errors) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/asyncapi_cable/diagnostics.rb', line 39

def root_container_expected?(errors)
  errors.any? do |error|
    error["data_pointer"].to_s.empty? && %w[object array].include?(error["type"])
  end
end

.serialized_container?(payload) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
# File 'lib/asyncapi_cable/diagnostics.rb', line 30

def serialized_container?(payload)
  return false unless payload.is_a?(String)

  parsed = JSON.parse(payload)
  parsed.is_a?(Hash) || parsed.is_a?(Array)
rescue JSON::ParserError
  false
end