Class: Fbe::Middleware::Formatter

Inherits:
Faraday::Logging::Formatter
  • Object
show all
Defined in:
lib/fbe/middleware/formatter.rb

Overview

Custom Faraday formatter that logs only error responses (4xx/5xx).

This formatter reduces log noise by only outputting details when HTTP requests fail. For 403 errors with JSON responses, it shows a compact warning with the error message. For other errors, it logs the full request/response details including headers and bodies.

Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2024-2025 Zerocracy

License

MIT

Examples:

Usage in Faraday middleware

connection = Faraday.new do |f|
  f.response :logger, nil, formatter: Fbe::Middleware::Formatter
end

Log output for 403 error

# GET https://api.github.com/repos/private/repo -> 403 / Repository access denied

Log output for other errors (500, 404, etc)

# GET https://api.example.com/endpoint HTTP/1.1
#   Content-Type: "application/json"
#   Authorization: "Bearer [FILTERED]"
#
#   {"query": "data"}
# HTTP/1.1 500
#   Content-Type: "text/html"
#
#   Internal Server Error

Instance Method Summary collapse

Instance Method Details

#request(http) ⇒ void

This method returns an undefined value.

Captures HTTP request details for later use in error logging.

Parameters:

  • http (Hash)

    Request data including method, url, headers, and body



46
47
48
# File 'lib/fbe/middleware/formatter.rb', line 46

def request(http)
  @req = http
end

#response(http) ⇒ void

Note:

Only logs when status >= 400

Note:

Special handling for 403 JSON responses to show compact error message

This method returns an undefined value.

Logs HTTP response details only for error responses (4xx/5xx).

Parameters:

  • http (Hash)

    Response data including status, headers, and body



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/fbe/middleware/formatter.rb', line 56

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
  if http.status >= 500 && http.response_headers['content-type']&.start_with?('text')
    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&.ellipsized(100, :right)))
      ].join("\n")
    )
    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