Builtin Library
README.md
world_refusal
The copy a player reads when a world will not open. The publishing backend answers a refused world with an HTTP status and a body; this module turns the part of that answer a reader can act on — the status, and whether the viewer holds a credential — into one sentence written for the visitor, plus the route onward.
Every sentence is read from the library catalog
(locales/<tag>/world_refusal.json) in the player's language, with the site
host it is given as its one parameter. A response body never reaches the text, so an auth error,
a signed URL or a token that arrives in one is read by the caller's log and
by nothing on screen.
What a refusal can and cannot say apart
| Answer | Reads as |
|---|---|
| 401 / 403, signed out | the credential is the gate; the route is to sign in |
| 401 / 403, signed in | the account on hand is the wrong one |
| 404 | one answer covers a world that published nothing, a private world this viewer may not read, and a guid naming no world — the copy states what holds for all three |
| anything else | an answer the reader cannot act on beyond trying again |
Exports
M.httpStatus(errText: any) -> number?— the status out of the engine'sHTTP <status>: <body>envelope, or nil when the string names none.M.cannotResolve(opts: { status: number?, signedIn: boolean?, site: string? }) -> string— the sentence for a refused resolve.M.cannotReachServer(opts: { status: number?, site: string? }) -> string: the sentence for a sign-in service that refused to name the live server a world opens on; a 401 / 403 routes to signing in again.M.nothingToPlay() -> string— the sentence for a published version that arrived with no content.M.unexpected() -> string— the sentence for a fault the reader can only retry.M.worldNotFound() -> string: the sentence for a world no record answers for this viewer.M.cannotEdit() -> string: the sentence for an edit of a world this account may not write to.M.protocolDetail(err: any) -> string— the backend's answer as one bounded line for the log and the admin-only banner line; an error object is encoded, so the log carries what the backend said.
Usage
local WorldRefusal = require("@builtin::modules.world_refusal")
local status = WorldRefusal.httpStatus(resolved.error)
log.error(("resolve refused: %s"):format(WorldRefusal.protocolDetail(resolved.error)))
showTerminal(WorldRefusal.cannotResolve({
status = status,
signedIn = jwt ~= nil,
site = issuer,
}))