apiResponse

Shape checks for parsed response bodies: the one place a caller learns whether a body holds what its endpoint promised, before it iterates or indexes it.

Members

(static, constant) ERROR_ABANDONED

res.error value when the pool completed a queued read without sending it, because nobody was waiting for the answer any more (apiPool.settleIfCallerGone).

Default Value
  • abandoned

(static, constant) ERROR_UNEXPECTED_SHAPE

res.error value when a 200's body is not the shape its request expected.

Default Value
  • unexpectedShape

(static, constant) EXPECT_LIST

req.expect value for an endpoint that answers with a bare array (ApiClient.listReq).

Default Value
  • list

Methods

(static) enforceShape(req, res) → {object}

Holds a pool response to the shape its request declared. ApiTask runs every response through this, so a caller of a list request never sees a body it cannot iterate.

For a request built with expect: "list", an ok response leaves with json set to the list (unwrapped by listFrom), or, when the body holds none, with ok = false, json = invalid and error = "unexpectedShape". statusCode stays the server's, so a log line still says what came back. Reporting it as not-ok is deliberate: every caller already treats not ok as "no answer", which is what an unreadable body is. Any other response is returned untouched.

Parameters:
NameTypeDescription
reqobject

the request AA the response answers

resobject

the pool response AA { requestId, ok, statusCode, json, text }; modified in place

Returns:

res

Type: 
object

(static) expectsList(req) → {boolean}

Whether a request declared that its endpoint answers with a bare array (ApiClient.listReq).

Parameters:
NameTypeDescription
reqdynamic

a request AA, or invalid

Returns:

true for a list request

Type: 
boolean

(static) jsonFailure(res) → {string}

Why a request that should have answered with JSON did not, in the few words a warning log line needs, or "" when the reply is usable. A caller that shows a failure state keeps the cause for its log and tells its screen only that the load failed.

The shapes are the pool's: invalid from fetchRes when the caller's wait ran out; no statusCode when roku-requests gave up waiting; a negative curl code for a connection that failed; statusCode 0 when ApiTask could not make the request at all.

Parameters:
NameTypeDescription
resdynamic

a pool response AA, or invalid

Returns:

"" for an ok reply with a parsed body, otherwise the cause

Type: 
string

(static) listFrom(json) → {dynamic}

Returns the list a list endpoint answered with, or invalid when the body holds none.

BrightScript iterates an AA's KEYS, so a body that is an object instead of an array does not fail softly: for each item in json hands back key strings, and the first item.Field (or a json[0]) is a runtime error that kills the app.

Also accepts the { Items: [...] } query-result wrapper. Stock Jellyfin does not send it for bare-array endpoints, but a server has sent exactly that for /Items/Latest in the field, and its Items is the same list, so reading it shows the user their content where rejecting it would leave the row empty on every retry. The same property makes this the reader for a query-result endpoint too, when a caller wants its list and nothing else.

invalid means "no list", which callers must treat as NO ANSWER, not as an authoritative empty list. An empty array is returned as-is and is the only way to say "empty".

Parameters:
NameTypeDescription
jsondynamic

a parsed response body (res.json), any type

Returns:

the roArray, or invalid

Type: 
dynamic

(static) noAnswer(res) → {boolean}

True when a request got no answer at all: the caller's wait ran out, or roku-requests gave up waiting. Distinct from a refusal (an HTTP error) or a network failure, because the server may still be working on the request.

Parameters:
NameTypeDescription
resdynamic

a pool response AA, or invalid

Returns:
Type: 
boolean