class Fbe::Middleware::Formatter

License
MIT
Copyright
Copyright © 2024-2025 Zerocracy
Author

Yegor Bugayenko (yegor256@gmail.com)
# Internal Server Error
#
# Content-Type: “text/html”
# HTTP/1.1 500
# {“query”: “data”}
#
# Authorization: “Bearer [FILTERED]”
# Content-Type: “application/json”
# GET api.example.com/endpoint HTTP/1.1
@example Log output for other errors (500, 404, etc)
# GET api.github.com/repos/private/repo -> 403 / Repository access denied
@example Log output for 403 error
end
f.response :logger, nil, formatter: Fbe::Middleware::Formatter
connection = Faraday.new do |f|
@example Usage in Faraday middleware
request/response details including headers and bodies.
warning with the error message. For other errors, it logs the full
requests fail. For 403 errors with JSON responses, it shows a compact
This formatter reduces log noise by only outputting details when HTTP
Custom Faraday formatter that logs only error responses (4xx/5xx).

def dump_headers(headers)

Returns:
  • (String) - The formatted headers, or an empty string if input was nil

Parameters:
  • headers (Hash, nil) -- The headers to format
def dump_headers(headers)
  return '' if headers.nil?
  headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
end

def request(http)

Returns:
  • (void) -

Parameters:
  • http (Hash) -- Request data including method, url, headers, and body
def request(http)
  @req = http
end

def response(http)

Other tags:
    Note: - Special handling for 403 JSON responses to show compact error message
    Note: - Only logs when status >= 400

Returns:
  • (void) -

Parameters:
  • http (Hash) -- Response data including status, headers, and body
def response(http)
  return if http.status < 400
  if http.status == 403 && http.response_headers['content-type'].start_with?('application/json')
    warn(
      [
        "#{@req.method.upcase} #{apply_filters(@req.url.to_s)}",
        '->',
        http.status,
        '/',
        JSON.parse(http.response_body)['message']
      ].join(' ')
    )
    return
  end
  error(
    [
      "#{@req.method.upcase} #{apply_filters(@req.url.to_s)} HTTP/1.1",
      shifted(apply_filters(dump_headers(@req.request_headers))),
      '',
      shifted(apply_filters(@req.request_body)),
      "HTTP/1.1 #{http.status}",
      shifted(apply_filters(dump_headers(http.response_headers))),
      '',
      shifted(apply_filters(http.response_body))
    ].join("\n")
  )
end

def shifted(txt)

Returns:
  • (String) - The indented text, or an empty string if input was nil

Parameters:
  • txt (String, nil) -- The text to indent
def shifted(txt)
  return '' if txt.nil?
  "  #{txt.gsub("\n", "\n  ")}"
end