Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Faraday to >= 2.0 #406

Merged
merged 5 commits into from
May 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/danger.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name: PR Linter
on: [pull_request]
jobs:
lint:
danger:
runs-on: ubuntu-latest
env:
BUNDLE_GEMFILE: ${{ github.workspace }}/Gemfile.danger
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6.5
ruby-version: 2.6
bundler-cache: true
- run: |
# the personal token is public, this is ok, base64 encode to avoid tripping Github
TOKEN=$(echo -n NWY1ZmM5MzEyMzNlYWY4OTZiOGU3MmI3MWQ3Mzk0MzgxMWE4OGVmYwo= | base64 --decode)
DANGER_GITHUB_API_TOKEN=$TOKEN bundle exec danger --verbose
DANGER_GITHUB_API_TOKEN=$TOKEN bundle exec danger --verbose
13 changes: 13 additions & 0 deletions .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Rubocop
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
bundler-cache: true
- run: bundle exec rubocop
11 changes: 4 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ jobs:
strategy:
matrix:
entry:
- { ruby: 2.5.3 }
- { ruby: 2.6.2 }
- { ruby: 2.7.1 }
- { ruby: 2.7.1, concurrency: async-websocket }
- { ruby: 3.0.2 }
- { ruby: 3.1.1 }
- { ruby: "2.7" }
- { ruby: "2.7", concurrency: async-websocket }
- { ruby: "3.0" }
- { ruby: "3.1" }
- { ruby: ruby-head, ignore: true }
- { ruby: jruby-head, ignore: true }
name: test (ruby=${{ matrix.entry.ruby }}, concurrency=${{ matrix.entry.concurrency || 'none' }})
Expand All @@ -34,4 +32,3 @@ jobs:
run: |
bundle install
bundle exec rake

8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
.env
pkg
Gemfile.lock
.DS_Store
.bundle
.byebug_history
.env
.idea
.rspec_status
.ruby-version
Gemfile.lock
pkg
3 changes: 2 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ inherit_from: .rubocop_todo.yml

require:
- rubocop-performance
- rubocop-rake
- rubocop-rspec

AllCops:
TargetRubyVersion: 2.5
TargetRubyVersion: 2.7
NewCops: enable
DisplayCopNames: true
Exclude:
Expand Down
32 changes: 22 additions & 10 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2022-03-12 19:25:15 UTC using RuboCop version 1.26.0.
# on 2022-05-04 06:11:49 UTC using RuboCop version 1.26.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
# Configuration parameters: Include.
# Include: **/*.gemspec
Gemspec/RequiredRubyVersion:
Exclude:
- 'slack-ruby-client.gemspec'

# Offense count: 1
# Configuration parameters: AllowedMethods.
# AllowedMethods: enums
Expand Down Expand Up @@ -129,7 +122,7 @@ RSpec/FilePath:
RSpec/MessageSpies:
EnforcedStyle: receive

# Offense count: 95
# Offense count: 96
RSpec/MultipleExpectations:
Max: 5

Expand All @@ -144,7 +137,7 @@ RSpec/NamedSubject:
Exclude:
- 'spec/slack/web/api/mixins/conversations_list_spec.rb'

# Offense count: 48
# Offense count: 50
RSpec/NestedGroups:
Max: 6

Expand All @@ -162,6 +155,13 @@ RSpec/SubjectStub:
- 'spec/slack/web/api/mixins/conversations_spec.rb'
- 'spec/slack/web/api/mixins/users_spec.rb'

# Offense count: 4
# This cop supports safe auto-correction (--auto-correct).
# Configuration parameters: .
# SupportedStyles: constant, string
RSpec/VerifiedDoubleReference:
EnforcedStyle: string

# Offense count: 12
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles:
Expand All @@ -171,6 +171,12 @@ RSpec/VerifiedDoubles:
- 'spec/slack/web/faraday/response/raise_error_spec.rb'
- 'spec/support/real_time/connected_client.rb'

# Offense count: 1
# This cop supports safe auto-correction (--auto-correct).
Rake/Desc:
Exclude:
- 'lib/tasks/git.rake'

# Offense count: 4
# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, IgnoredMethods.
# SupportedStyles: annotated, template, unannotated
Expand Down Expand Up @@ -206,6 +212,12 @@ Style/OptionalBooleanParameter:
Exclude:
- 'spec/support/queue_with_timeout.rb'

# Offense count: 1
# This cop supports unsafe auto-correction (--auto-correct-all).
Style/SlicingWithRange:
Exclude:
- 'lib/slack/web/api/mixins/ids.id.rb'

# Offense count: 1
# This cop supports unsafe auto-correction (--auto-correct-all).
# Configuration parameters: Mode.
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
### 1.0.1 (Next)
### 1.1.0 (Next)

* [#400](https://github.com/slack-ruby/slack-ruby-client/pull/400): Replace Travis-CI with GitHub Actions - [@dblock](https://github.com/dblock).
* [#401](https://github.com/slack-ruby/slack-ruby-client/pull/401): Upgraded RuboCop to 1.26.0 - [@dblock](https://github.com/dblock).
* [#401](https://github.com/slack-ruby/slack-ruby-client/pull/401): Added support for Ruby 3.1.1 - [@dblock](https://github.com/dblock).
* [#405](https://github.com/slack-ruby/slack-ruby-client/pull/405): Added `admin_apps_requests_cancel`, `admin_users_unsupportedVersions_export`, `bookmarks_add`, `bookmarks_edit`, `bookmarks_list`, `bookmarks_remove` - [@dblock](https://github.com/dblock).
* [#404](https://github.com/slack-ruby/slack-ruby-client/pull/404): Update `chat_update` method not to raise error with parameter which contains only `reply_broadcast` - [@colorbox](https://github.com/colorbox).
* [#406](https://github.com/slack-ruby/slack-ruby-client/pull/406): Update Faraday to `>= 2.0` - [@schinery](https://github.com/slack-ruby/slack-ruby-client/pull/406).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's bump the version to 1.1 (version.rb, etc.)

* [#406](https://github.com/slack-ruby/slack-ruby-client/pull/406): Removed support for Ruby 2.5 and 2.6 - [@schinery](https://github.com/slack-ruby/slack-ruby-client/pull/406).
* [#406](https://github.com/slack-ruby/slack-ruby-client/pull/406): Test against latest Ruby 2.7, 3.0 and 3.1 - [@schinery](https://github.com/slack-ruby/slack-ruby-client/pull/406).
* [#406](https://github.com/slack-ruby/slack-ruby-client/pull/406): Upgraded RuboCop to 1.26.1 and lock to version - [@schinery](https://github.com/slack-ruby/slack-ruby-client/pull/406).
* [#406](https://github.com/slack-ruby/slack-ruby-client/pull/406): Updated Danger PR Linter GitHub action to use separate `Gemfile` - [@schinery](https://github.com/slack-ruby/slack-ruby-client/pull/406).
* Your contribution here.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this one back.


### 1.0.0 (2021/12/21)
Expand Down
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ end
group :test do
gem 'activesupport'
gem 'erubis'
gem 'faraday-typhoeus'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this becoming a gem dependency? Does it belong in .gemspec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added as testing dependency because it was required for the 'non default adapter' spec in spec/slack/web/client_spec.rb:177 and the adapters are no longer bundled in.

gem 'json-schema'
gem 'rake', '~> 13'
gem 'rspec'
gem 'rubocop', '~> 1.26.0'
gem 'rubocop', '1.26.1' # Lock to specific version to avoid breaking cops/changes
gem 'rubocop-performance'
gem 'rubocop-rake'
gem 'rubocop-rspec'
gem 'slack-ruby-danger', '~> 0.2.0', require: false
gem 'timecop'
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
# https://github.com/vcr/vcr/pull/907
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.danger
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source 'https://rubygems.org'

group :test do
gem 'danger-toc', '~> 0.2.0', require: false
gem 'slack-ruby-danger', '~> 0.2.0', require: false
end
3 changes: 2 additions & 1 deletion lib/slack-ruby-client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

# Web API
require 'faraday'
require 'faraday_middleware'
require 'faraday/mashify'
require 'faraday/multipart'
require 'json'
require 'logger'
begin
Expand Down
2 changes: 1 addition & 1 deletion lib/slack/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true
module Slack
VERSION = '1.0.1'
VERSION = '1.1.0'
end
8 changes: 4 additions & 4 deletions lib/slack/web/faraday/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ def connection
options[:request] = request_options if request_options.any?

::Faraday::Connection.new(endpoint, options) do |connection|
connection.use ::Faraday::Request::Multipart
connection.use ::Faraday::Request::UrlEncoded
connection.request :multipart
connection.request :url_encoded
connection.use ::Slack::Web::Faraday::Response::RaiseError
connection.use ::FaradayMiddleware::Mashify, mash_class: Slack::Messages::Message
connection.use ::FaradayMiddleware::ParseJson
connection.response :mashify, mash_class: Slack::Messages::Message
connection.response :json, content_type: /\b*$/
Copy link
Collaborator

@dblock dblock May 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is any content type, isn't it? Do any specs fail if you remove content_type here? I think not, and it's the old behavior that basically says "try to parse anything, which now raises ::Faraday::ParsingError, which we handle properly".

Remove comment and TODO above.

Copy link
Contributor Author

@schinery schinery May 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is any content type, isn't it? Do any specs fail if you remove content_type here? I think not, and it's the old behavior that basically says "try to parse anything, which now raises ::Faraday::ParsingError, which we handle properly".

If we remove this content_type: option then the <html></html> response specs will fail because the default for the JSON middleware parsing is /\bjson$/, so we wouldn't attempt to parse if a 500 HTML response was returned and we end up with the undefined method 'map' for nil:NilClass mention in the initial PR description.

I guess there are two options:

  1. Leave as is it now meaning that it will try and parse any response Slack returns, which I think as you say is the old behaviour handled by the deprecated ::FaradayMiddleware::ParseJson middleware
  2. Make the content types stricter and set it to only attempt to parse JSON or HTML content types (or whatever we know is returned) as we can set an array of content types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment and TODO above.

Removed 👍🏻

connection.use ::Slack::Web::Faraday::Response::WrapError
connection.response :logger, logger if logger
connection.adapter adapter
Expand Down
2 changes: 2 additions & 0 deletions lib/slack/web/faraday/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ def request(method, path, options)
request.options.merge!(options.delete(:request)) if options.key?(:request)
end
response.body
rescue ::Faraday::ParsingError => e
raise Slack::Web::Api::Errors::ParsingError, e.response
end
end
end
Expand Down
12 changes: 2 additions & 10 deletions lib/slack/web/faraday/response/raise_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Slack
module Web
module Faraday
module Response
class RaiseError < ::Faraday::Response::Middleware
class RaiseError < ::Faraday::Middleware
def on_complete(env)
raise Slack::Web::Api::Errors::TooManyRequestsError, env.response if env.status == 429

Expand All @@ -13,19 +13,11 @@ def on_complete(env)
return unless body
return if body['ok']

error_message =
body['error'] || body['errors'].map { |message| message['error'] }.join(',')

error_message = body['error'] || body['errors'].map { |message| message['error'] }.join(',')
error_class = Slack::Web::Api::Errors::ERROR_CLASSES[error_message]
error_class ||= Slack::Web::Api::Errors::SlackError
raise error_class.new(error_message, env.response)
end

def call(env)
super
rescue ::Faraday::ParsingError
raise Slack::Web::Api::Errors::ParsingError, env.response
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/slack/web/faraday/response/wrap_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Slack
module Web
module Faraday
module Response
class WrapError < ::Faraday::Response::Middleware
class WrapError < ::Faraday::Middleware
UNAVAILABLE_ERROR_STATUSES = (500..599).freeze

def on_complete(env)
Expand Down
6 changes: 4 additions & 2 deletions slack-ruby-client.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ Gem::Specification.new do |s|
s.authors = ['Daniel Doubrovkine']
s.email = 'dblock@dblock.org'
s.platform = Gem::Platform::RUBY
s.required_ruby_version = '>= 2.7'
s.required_rubygems_version = '>= 1.3.6'
s.files = `git ls-files`.split("\n")
s.require_paths = ['lib']
s.homepage = 'http://github.com/slack-ruby/slack-ruby-client'
s.licenses = ['MIT']
s.summary = 'Slack Web and RealTime API client.'
s.add_dependency 'faraday', '>= 1.0'
s.add_dependency 'faraday_middleware'
s.add_dependency 'faraday', '>= 2.0'
s.add_dependency 'faraday-mashify'
s.add_dependency 'faraday-multipart'
s.add_dependency 'gli'
s.add_dependency 'hashie'
s.add_dependency 'websocket-driver'
Expand Down
32 changes: 25 additions & 7 deletions spec/slack/web/client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
require 'spec_helper'
require 'faraday/typhoeus'

RSpec.describe Slack::Web::Client do
before do
Expand Down Expand Up @@ -275,13 +276,28 @@
end

context 'parsing error' do
before { stub_slack_request.to_return(body: '<html></html>') }
context 'when the response is not JSON' do
before do
stub_slack_request.to_return(body: '<html></html>', headers: { 'Content-Type' => 'text/html' })
end

it 'raises ParsingError' do
expect { request }.to raise_error(Slack::Web::Api::Errors::ParsingError).with_message('parsing_error')
expect(exception.response.body).to eq('<html></html>')
expect(exception.cause).to be_a(Faraday::ParsingError)
expect(exception.cause.cause.cause).to be_a(JSON::ParserError)
it 'raises ParsingError' do
expect { request }.to raise_error(Slack::Web::Api::Errors::ParsingError).with_message('parsing_error')
expect(exception.response.body).to eq('<html></html>')
expect(exception.cause).to be_a(Faraday::ParsingError)
expect(exception.cause.cause).to be_a(JSON::ParserError)
end
end

context 'when the response is malformed JSON' do
before { stub_slack_request.to_return(body: '{') }

it 'raises ParsingError' do
expect { request }.to raise_error(Slack::Web::Api::Errors::ParsingError).with_message('parsing_error')
expect(exception.response.body).to eq('{')
expect(exception.cause).to be_a(Faraday::ParsingError)
expect(exception.cause.cause).to be_a(JSON::ParserError)
end
end
end

Expand Down Expand Up @@ -318,7 +334,9 @@
end

context 'with a HTML response' do
before { stub_slack_request.to_return(status: 500, body: '<html></html>') }
before do
stub_slack_request.to_return(status: 500, body: '<html></html>', headers: { 'Content-Type' => 'text/html' })
end

it 'raises UnavailableError' do
expect { request }.to raise_error(Slack::Web::Api::Errors::UnavailableError).with_message('unavailable_error')
Expand Down