Module: Wfirma::Status

Defined in:
lib/wfirma/status.rb

Overview

wFirma answers HTTP 200 for everything, so the top-level status code is the real outcome. This is the whole documented set (doc.wfirma.pl, "Komunikaty błędów"), split by what the caller can do about it.

A code that describes the record reaches the caller as a Result. A code that aborts the request is raised: there is no record to report on, so a Result would carry an empty error list and the reason would be lost.

Constant Summary collapse

OK =
"OK".freeze
RESULT_CODES =

NOT FOUND is grouped with the aborting codes in wFirma's docs, but it answers a record the caller named - an edit of an id that is gone, a lookup that matched nothing - so it is an outcome, not a transport failure, and it stays a Result.

[OK, "ERROR", "NOT FOUND"].freeze
ABORTING =
{
  "AUTH" => [AuthError, "authentication failed - check accessKey/secretKey/appKey"],
  "AUTH FAILED LIMIT WAIT 5 MINUTES" =>
    [AuthError, "too many failed authentication attempts - wait 5 minutes"],
  "ACCESS DENIED" => [AccessDeniedError, "this account may not perform that action"],
  "DENIED SCOPE REQUESTED" =>
    [AccessDeniedError, "the OAuth authorization does not cover that scope"],
  "ACTION NOT FOUND" => [RequestError, "no such action - check the module and action names"],
  "COMPANY ID REQUIRED" =>
    [RequestError, "the account holds several companies - pass company_id"],
  "INPUT ERROR" => [RequestError, "wFirma could not read the request body"],
  "TOTAL REQUESTS LIMIT EXCEEDED" => [RateLimitError, "request limit exceeded"],
  "TOTAL EXECUTION TIME LIMIT EXCEEDED" => [RateLimitError, "execution time limit exceeded"],
  "OUT OF SERVICE" => [ServiceUnavailableError, "the API is temporarily out of service"],
  "SNAPSHOT LOCK" => [ServiceUnavailableError, "the company is being restored from a backup"],
  "FATAL" => [ServerError, "internal wFirma error"]
}.freeze
UNKNOWN =
[ApiError, "unrecognised status code"].freeze

Class Method Summary collapse

Class Method Details

.error_for(code, message: nil, errors: []) ⇒ Object

The exception for this status code, or nil when the code belongs in a Result. An unrecognised code is raised rather than passed through: this exists so a failure is never silent, and wFirma may add codes.



43
44
45
46
47
48
49
50
51
52
# File 'lib/wfirma/status.rb', line 43

def error_for(code, message: nil, errors: [])
  code = code.to_s
  return nil if RESULT_CODES.include?(code)

  error_class, explanation = ABORTING.fetch(code, UNKNOWN)
  error_class.new(
    message_for(code, explanation, message, errors),
    status_code: code, errors: errors
  )
end

.message_for(code, explanation, message, errors) ⇒ Object



54
55
56
57
58
# File 'lib/wfirma/status.rb', line 54

def message_for(code, explanation, message, errors)
  detail = message.to_s.empty? ? Array(errors).join("; ") : message.to_s
  text = "wFirma: #{explanation} (status #{code.empty? ? "missing" : code})"
  detail.empty? ? text : "#{text}: #{detail}"
end