Class: X::Problem
- Inherits:
-
Object
- Object
- X::Problem
- Defined in:
- x-core/lib/x/core/problem.rb
Overview
A problem the API described, in a response that failed or in one that otherwise succeeded
The API describes what went wrong the same way whether it refused the request, which raises an HTTPError whose HTTPError#problem is one of these, or answered it with the resources it could and named the rest as errors, which the object layer reads as the problems of a resource or a page. Code that acts on the reason rather than logging it reads the same object either way.
Instance Attribute Summary collapse
-
#attrs ⇒ Hash{String => Object}
(also: #to_h)
readonly
The raw attributes of the problem.
Class Method Summary collapse
-
.all_from(body) ⇒ Array<Problem>
The problems a response body reports.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Check whether another problem is the same problem.
-
#about?(resource) ⇒ Boolean
Check whether the problem is about a resource.
-
#as_json ⇒ Hash{String => Object}
The attributes, as a JSON encoder and ActiveSupport read them.
-
#detail ⇒ String?
The description of this occurrence of the problem.
-
#disconnect? ⇒ Boolean
Check whether the problem is an operational-disconnect of a stream.
-
#encode_with(coder) ⇒ void
Write the state Marshal writes as YAML.
-
#hash ⇒ Integer
The hash of the problem, which equal problems share.
-
#init_with(coder) ⇒ void
Restore a problem YAML read, frozen, as Marshal restores one.
-
#initialize(attrs) ⇒ Problem
constructor
Initialize a problem from the attributes the API reported.
-
#inspect ⇒ String
Summarize the problem for the console.
-
#marshal_dump ⇒ Array(Integer, Hash{String => Object})
The state Marshal writes.
-
#marshal_load(state) ⇒ void
Restore a problem Marshal read, frozen as the problem that was written was.
-
#message ⇒ String?
The message the API gave for a request it refused.
-
#not_found? ⇒ Boolean
Check whether the problem is a resource that was not found.
-
#parameter ⇒ String?
The request parameter the problem concerns.
-
#resource_id ⇒ String?
The identifier of the resource the problem concerns.
-
#resource_type ⇒ String?
The kind of resource the problem concerns.
-
#title ⇒ String?
The short, general description of the problem.
-
#to_json(state = nil) ⇒ String
The attributes as JSON.
-
#type ⇒ String?
The URI that identifies the kind of problem.
-
#usage_capped? ⇒ Boolean
Check whether the problem is the usage cap of the project, reached for the month.
-
#value ⇒ Object?
The value of the parameter the problem concerns.
Constructor Details
#initialize(attrs) ⇒ Problem
Initialize a problem from the attributes the API reported
59 60 61 62 |
# File 'x-core/lib/x/core/problem.rb', line 59 def initialize(attrs) @attrs = deep_freeze(attrs) freeze end |
Instance Attribute Details
#attrs ⇒ Hash{String => Object} (readonly) Also known as: to_h
The raw attributes of the problem
30 31 32 |
# File 'x-core/lib/x/core/problem.rb', line 30 def attrs @attrs end |
Class Method Details
.all_from(body) ⇒ Array<Problem>
The problems a response body reports
47 48 49 50 |
# File 'x-core/lib/x/core/problem.rb', line 47 def self.all_from(body) entries = Array(body.to_h["errors"]) #: Array[untyped] entries.filter_map { |attrs| Hash.try_convert(attrs)&.then { |hash| new(hash) } }.freeze end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Check whether another problem is the same problem
195 |
# File 'x-core/lib/x/core/problem.rb', line 195 def ==(other) = other.instance_of?(self.class) && attrs.eql?(other.attrs) |
#about?(resource) ⇒ Boolean
Check whether the problem is about a resource
The resource_id of a problem is the String the API gave, where the resources of x-objects hold an Integer identifier, so the identifier of the resource, or the identifier given, is compared with it as a String. A username names the user a problem names by it. A problem that names no resource is about none.
180 181 182 183 184 185 186 |
# File 'x-core/lib/x/core/problem.rb', line 180 def about?(resource) id = case resource when Integer, String then resource else resource.id end resource_id.eql?(id.to_s) end |
#as_json ⇒ Hash{String => Object}
The attributes, as a JSON encoder and ActiveSupport read them
ActiveSupport's Object#as_json would otherwise read the instance variables, which is the same Hash under another name.
215 |
# File 'x-core/lib/x/core/problem.rb', line 215 def as_json(*) = attrs |
#detail ⇒ String?
The description of this occurrence of the problem
78 |
# File 'x-core/lib/x/core/problem.rb', line 78 def detail = attrs["detail"] |
#disconnect? ⇒ Boolean
Check whether the problem is an operational-disconnect of a stream
X sends one before it closes a stream for its own reasons. A stream reconnects after a line that holds such problems alone, as it does after a connection that dropped.
153 |
# File 'x-core/lib/x/core/problem.rb', line 153 def disconnect? = type.to_s.end_with?("/operational-disconnect") |
#encode_with(coder) ⇒ void
This method returns an undefined value.
Write the state Marshal writes as YAML
YAML would write the instance variables of the problem, and read them back into one that is not frozen, so it says how it is written: each part of the state Marshal writes, under its name.
275 |
# File 'x-core/lib/x/core/problem.rb', line 275 def encode_with(coder) = YAML_KEYS.zip(marshal_dump) { |key, value| coder[key] = value } |
#hash ⇒ Integer
The hash of the problem, which equal problems share
204 |
# File 'x-core/lib/x/core/problem.rb', line 204 def hash = [self.class, attrs].hash |
#init_with(coder) ⇒ void
This method returns an undefined value.
Restore a problem YAML read, frozen, as Marshal restores one
285 |
# File 'x-core/lib/x/core/problem.rb', line 285 def init_with(coder) = marshal_load(coder.map.values_at(*YAML_KEYS)) |
#inspect ⇒ String
Summarize the problem for the console
A problem the API described in a response that succeeded carries a detail, and one it named among the errors of a request it refused carries a message in its place, so the summary reads whichever of the two it holds.
237 |
# File 'x-core/lib/x/core/problem.rb', line 237 def inspect = "#<#{self.class} #{[title, detail || ].compact.join(": ")}>" |
#marshal_dump ⇒ Array(Integer, Hash{String => Object})
The state Marshal writes
What is written is plain data, led by the number of its format, so that a problem written by one release of 1.x is read by a later one: its attributes, as the API described it.
248 |
# File 'x-core/lib/x/core/problem.rb', line 248 def marshal_dump = [MARSHAL_FORMAT, attrs] |
#marshal_load(state) ⇒ void
This method returns an undefined value.
Restore a problem Marshal read, frozen as the problem that was written was
258 259 260 261 262 263 |
# File 'x-core/lib/x/core/problem.rb', line 258 def marshal_load(state) format, attrs = state raise UnsupportedMarshalFormat, "#{self.class} reads format #{MARSHAL_FORMAT} of Marshal, not #{format.inspect}" unless MARSHAL_FORMAT.eql?(format) initialize(attrs) end |
#message ⇒ String?
The message the API gave for a request it refused
The errors of a request the API refused carry a message where the problems of a response that succeeded carry a detail, so a problem read from a failed request reads as one of either.
135 |
# File 'x-core/lib/x/core/problem.rb', line 135 def = attrs["message"] |
#not_found? ⇒ Boolean
Check whether the problem is a resource that was not found
143 |
# File 'x-core/lib/x/core/problem.rb', line 143 def not_found? = type.to_s.end_with?("/resource-not-found") |
#parameter ⇒ String?
The request parameter the problem concerns
114 |
# File 'x-core/lib/x/core/problem.rb', line 114 def parameter = attrs["parameter"] |
#resource_id ⇒ String?
The identifier of the resource the problem concerns
It is the String the API gave, whatever the kind of resource, since the API names a user by a username as often as by an identifier, and a space, a place, or media by an identifier that is not a number; #about? compares it with a resource, or the identifier of one, as a String.
106 |
# File 'x-core/lib/x/core/problem.rb', line 106 def resource_id = attrs["resource_id"] |
#resource_type ⇒ String?
The kind of resource the problem concerns
94 |
# File 'x-core/lib/x/core/problem.rb', line 94 def resource_type = attrs["resource_type"] |
#title ⇒ String?
The short, general description of the problem
70 |
# File 'x-core/lib/x/core/problem.rb', line 70 def title = attrs["title"] |
#to_json(state = nil) ⇒ String
The attributes as JSON
224 |
# File 'x-core/lib/x/core/problem.rb', line 224 def to_json(state = nil) = as_json.to_json(state) |
#type ⇒ String?
The URI that identifies the kind of problem
86 |
# File 'x-core/lib/x/core/problem.rb', line 86 def type = attrs["type"] |
#usage_capped? ⇒ Boolean
Check whether the problem is the usage cap of the project, reached for the month
X refuses every request of a project that has used the posts its plan allows for the month with a 429 of this problem, until the month ends, so a client neither waits for it nor sends the request again, and a stream does not reconnect after it, however its rate limits are set.
165 |
# File 'x-core/lib/x/core/problem.rb', line 165 def usage_capped? = type.to_s.end_with?("/usage-capped") |
#value ⇒ Object?
The value of the parameter the problem concerns
It is the value the API gave, as the request sent it, so an identifier is a String, as resource_id is.
124 |
# File 'x-core/lib/x/core/problem.rb', line 124 def value = attrs["value"] |