Compare commits

...

64 Commits

Author SHA1 Message Date
Matt
2f3a7da89e
Version bump to 0.17.4 2021-02-06 09:30:52 +00:00
Mervyn Chng
3e45edecab
Fix === for subclasses of deprecated classes (#1243) 2021-02-04 21:54:48 +01:00
Matt
a58e25b3dc
Fix 0.1x ci workflow (#1244) 2021-02-04 19:30:32 +00:00
Matheus Santana
a7dbb76c7e
NetHttp adapter: wrap Errno::EADDRNOTAVAIL (#1114)
Just as 148b99ee0fde8 also does but for the v0.1x releases.
2020-02-07 19:48:51 +00:00
technoweenie
54c5c2e96c change to v0.17.3 due to weird rubygems thing 2019-12-31 16:25:58 -07:00
risk danger olson
ebab004c4d
Merge pull request #1103 from lostisland/reship-0.17.2
version 0.17.2
2019-12-31 15:55:10 -07:00
Mattia
efead03688
Adds suggestions on how to upgrade to v1.0 in README.md (#1105) 2019-12-31 16:26:18 +00:00
technoweenie
098bdbeb25 Merge branch '0.1x' into reship-0.17.2 2019-12-30 08:14:49 -07:00
technoweenie
0d3ee6f2ca add deprecate pr to changelog 2019-12-30 07:39:52 -07:00
risk danger olson
e8a6662b6a
Merge pull request #1098 from lostisland/deprecate-opt-in
require FARADAY_DEPRECATE=warn to show Faraday v1.0 deprecation warnings
2019-12-30 07:29:58 -07:00
technoweenie
0456770abf fix attribution 2019-12-29 23:54:32 -07:00
technoweenie
926cc100e1 version 0.17.2 2019-12-29 23:46:13 -07:00
technoweenie
2b3fda9511 Merge branch '0.1x' into deprecate-opt-in 2019-12-29 22:40:41 -07:00
risk danger olson
9a395c8035
test 0.1x against ruby 2.7 (#1099)
* test against ruby 2.7

* fix ruby 2.7 warning

lib/faraday/adapter/net_http_persistent.rb:13: warning: Using the last
argument as keyword parameters is deprecated; maybe ** should be added to the
call

https://github.com/lostisland/faraday/pull/1099/checks?check_run_id=367324080
https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
2019-12-29 22:38:57 -07:00
technoweenie
04f1f7c0ea require FARADAY_DEPRECATE=warn to show Faraday v1.0 deprecation warnings 2019-12-29 18:59:44 -07:00
risk danger olson
cbde3d3240
Fix 1.9 syntax error (with Error fixes) (#1094)
* Fix 1.9 syntax error (with Error fixes)

0.1x is supposed to be 1.9-compat

* Fix CI for Ruby 2.3

Support for github action of ruby 2.3 was removed. Now according to
https://github.com/actions/setup-ruby/blob/master/action.yml
theminimal version is 2.4.

* improve how errors pull out exceptions and responses

* deprecate :response handling

* don't force response to be {}

* init these ivars

* dont re-init them

* how do i get this to init

Co-authored-by: Hiro Asari <asari.ruby@gmail.com>
Co-authored-by: Valentine Kiselev <mrexox@outlook.com>
Co-authored-by: Mattia <iMacTia@users.noreply.github.com>
2019-12-29 18:39:44 -07:00
Mattia
243dc9226f
Reverts changes in error classes hierarchy. (#1092) 2019-12-27 16:38:55 +00:00
Mattia
9b1fd02c90
Update CI to support Ruby 2.0+ (#1087) 2019-12-27 15:36:34 +00:00
Olle Jonsson
c56732cd0d [Ruby 2.7] Stops using &Proc.new for block forwarding.
Back-port 5ace0ea5ab82b49bb13648dcfd0272d068a82885
2019-11-28 20:58:49 +01:00
risk danger olson
9865ebbf8f
add release notes for Faraday v0.17.1 (#1082)
* add release notes for Faraday v0.17.1

* bump version to v0.17.1
2019-11-27 10:46:50 -07:00
risk danger olson
6fc084565e
Merge pull request #1081 from lostisland/0.1x-ruby-2.7-fixes
backport ruby 2.7 fixes to 0.1x
2019-11-27 10:37:01 -07:00
Aaron Patterson
b32566c3aa This fixes warnings on Ruby 2.7 (#1009) 2019-11-27 10:08:54 -07:00
risk danger olson
389ede471f
Merge pull request #1076 from lostisland/0.1x-deprecate-fixes-2
0.1x deprecate fixes 2
2019-11-20 09:48:20 -07:00
risk danger olson
b499d4f265
Merge pull request #1077 from BobbyMcWho/deprecate-changes
Remove the intermediate variable
2019-11-14 09:43:38 -07:00
Bobby McDonald
5099ebc724
Remove the intermediate variable 2019-11-14 11:19:38 -05:00
rick olson
8332622330 teach DeprecatedClass.proxy_class to accept a different ver 2019-11-13 16:59:01 -07:00
rick olson
34e28b65e7 remove usage of ===
https://rubystyle.guide/#no-case-equality
2019-11-13 16:57:43 -07:00
risk danger olson
2f1a8c9b75
Merge pull request #1066 from lostisland/0.1x-changelog
Add release notes from v0.9.2 - v0.17.0 to the Changelog
2019-11-06 10:06:00 -07:00
risk danger olson
a1fc91e6f1
update authors 2019-11-06 10:00:37 -07:00
rick olson
ceb17cda37 clean up that copy pasta 2019-10-23 12:50:32 -06:00
rick olson
d8282e1add update homepage, add changelog/source code/bug tracker urls, and include changelog and tests with gem file. 2019-10-23 12:45:42 -06:00
rick olson
4b9948232f Add release notes from v0.9.2 - v0.17.0 to the Changelog 2019-10-23 12:24:01 -06:00
risk danger olson
e77982adf1
Merge pull request #1064 from lostisland/0.1x-nil-error
0.1x nil error
2019-10-23 11:24:10 -06:00
rick olson
6ab10ad8ef remove references to deprecated error classes 2019-10-19 10:28:52 -06:00
rick olson
58e4b4064f introduce NilStatusError to the RaiseError middleware 2019-10-19 10:22:03 -06:00
risk danger olson
87003c2e2b
Merge pull request #1059 from lostisland/0.1x-deprecate-fix
0.1x deprecate fixes
2019-10-19 09:53:39 -06:00
rick olson
c4ebca8ac1 use rspec expect syntax to test the error handling 2019-10-18 09:16:08 -06:00
rick olson
620c4d1271 remove unnecessary #tap 2019-10-17 19:29:28 -06:00
risk danger olson
5b0ebf7ddd
Update lib/faraday/deprecate.rb
Co-Authored-By: Bobby McDonald <BobbyMcWho@users.noreply.github.com>
2019-10-17 19:27:56 -06:00
rick olson
6198c755a7 squelch this 2019-10-17 15:44:15 -06:00
risk danger olson
09b4ec7451
Merge pull request #1058 from lostisland/0.1x-spec
0.1x spec
2019-10-17 15:27:53 -06:00
rick olson
ddab77c026 allow deprecated exception classes to rescue the current exception class 2019-10-17 15:26:03 -06:00
rick olson
f2e86946d9 Teach proxy_class how to work with root-level superclasses 2019-10-17 15:23:08 -06:00
rick olson
f9199fc570 rspec junit formatter is unused 2019-10-17 14:30:07 -06:00
rick olson
9681395fe1 randomize spec order and disable monkey patching 2019-10-17 14:29:34 -06:00
rick olson
7a0f468c53 ignore docs dir on 0.1x 2019-10-17 14:07:57 -06:00
rick olson
e77b8d2829 Run rspec alongside test/unit 2019-10-17 14:07:41 -06:00
risk danger olson
a4e9bc2c19
Merge pull request #1054 from BobbyMcWho/create-faraday-deprecation-class
Create faraday deprecation class
2019-10-17 13:30:08 -06:00
rick olson
6af38097ff Merge branch '0.1x' into create-faraday-deprecation-class 2019-10-17 12:57:27 -06:00
risk danger olson
bee4af0982
Merge pull request #1055 from lostisland/0.1x-ci-update
replace travis config with gh actions
2019-10-17 11:49:43 -06:00
rick olson
f8e5a1e484 where we're going... we don't need... linting... 2019-10-17 11:41:03 -06:00
rick olson
b6ee4b4d4f update ci workflow in this branch only 2019-10-17 11:40:30 -06:00
rick olson
96adae8786 bring them back 2019-10-17 11:35:31 -06:00
rick olson
d2de3202d0 remove GH Actions config since it's only read from master 2019-10-17 11:34:34 -06:00
rick olson
2206f48b7c replace travis config with gh actions 2019-10-17 10:45:21 -06:00
Bobby McDonald
b409ace81b
Rescue correct error 2019-10-17 09:47:21 -04:00
Bobby McDonald
6e746fceef
Create Faraday Deprecate class.
This implementation warns
in stderr similar to Gem::Deprecate, but gives a semver instead of
a date like the default Gem::Deprecate does.
2019-10-17 09:46:28 -04:00
iMacTia
22b689d78f Version bump to 0.17.0 (rolling back 0.16.0 -> 0.16.2 releases from master). 2019-10-06 22:22:59 +01:00
iMacTia
9307883513 Version bump to 0.16.3 (rolling back 0.16.0 -> 0.16.2 releases from master). 2019-10-06 22:10:12 +01:00
Olle Jonsson
5637812d59
README: Travis build badge for branch master (#849) 2019-02-20 12:30:22 +01:00
Nick Presta
6f2ae82ea0 Explicitly require date for DateTime (#844) 2019-02-07 18:27:59 +00:00
Olle Jonsson
c80cf86c5a Travis: add 2.6.0 to CI matrix, remove sudo: false (#839) 2019-01-12 15:53:57 +00:00
Adam Steel
6cba2a83b5 Include instructions for using custom middleware (#836) 2018-11-30 10:34:13 +00:00
Mattia
1db93400b3
Version bump to 0.15.4 2018-11-27 10:55:37 +00:00
35 changed files with 1141 additions and 175 deletions

View File

@ -1,37 +1,44 @@
## Contributing
You can run the test suite against a live server by running `script/test`. It
automatically starts a test server in background. Only tests in
`test/adapters/*_test.rb` require a server, though.
In Faraday we always welcome new ideas and features, however we also have to ensure
that the overall code quality stays on reasonable levels.
For this reason, before adding any contribution to Faraday, we highly recommend reading this
quick guide to ensure your PR can be reviewed and approved as quickly as possible.
We are pushing towards a 1.0 release, when we will have to follow [Semantic
Versioning][semver]. If your patch includes changes to break compatibility,
note that so we can add it to the [Changelog][].
``` sh
# setup development dependencies
$ script/bootstrap
# run the whole suite
$ script/test
### Required Checks
# run only specific files
$ script/test excon patron
Before pushing your code and opening a PR, we recommend you run the following checks to avoid
our GitHub Actions Workflow to block your contribution.
# run tests using SSL
$ SSL=yes script/test
```bash
# Run unit tests and check code coverage
$ bundle exec rspec
# Run Rubocop and check code style
$ bundle exec rubocop
```
### New Features
When adding a feature Faraday:
When adding a feature in Faraday:
1. also add tests to cover your new feature.
2. if the feature is for an adapter, the **attempt** must be made to add the same feature to all other adapters as well.
3. start opening an issue describing how the new feature will work, and only after receiving the green light by the core team start working on the PR.
3. start opening an issue describing how the new feature will work, and only after receiving
the green light by the core team start working on the PR.
### New Middlewares
### New Middleware
We will accept middleware that:
1. is useful to a broader audience, but can be implemented relatively
simple; and
1. is useful to a broader audience, but can be implemented relatively simple; and
2. which isn't already present in [faraday_middleware][] project.
@ -43,10 +50,26 @@ We will accept adapters that:
1. are proven and may have better performance than existing ones; or
2. if they have features not present in included adapters.
We are pushing towards a 1.0 release, when we will have to follow [Semantic
Versioning][semver]. If your patch includes changes to break compatibility,
note that so we can add it to the [Changelog][].
[semver]: http://semver.org/
[changelog]: https://github.com/lostisland/faraday/releases
[faraday_middleware]: https://github.com/lostisland/faraday_middleware/wiki
### Changes to Faraday Website
The [Faraday Website][website] is included in the Faraday repository, under the `/docs` folder.
If you want to apply changes to it, please test it locally using `Jekyll`.
```bash
# Navigate into the /docs folder
$ cd docs
# Install Jekyll dependencies, this bundle is different from Faraday's one.
$ bundle install
# Run the Jekyll server with the Faraday website
$ bundle exec jekyll serve
# The site will now be reachable at http://127.0.0.1:4000/faraday/
```
[semver]: http://semver.org/
[changelog]: https://github.com/lostisland/faraday/releases
[faraday_middleware]: https://github.com/lostisland/faraday_middleware
[website]: https://lostisland.github.io/faraday

44
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: CI
on:
pull_request:
push:
branches: [master, 0.1x]
env:
GIT_COMMIT_SHA: ${{ github.sha }}
GIT_BRANCH: ${{ github.ref }}
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
ruby: ['2.4', '2.5', '2.6', '2.7']
steps:
- uses: actions/checkout@v1
- name: Set up RVM
run: |
curl -sSL https://get.rvm.io | bash
- name: Set up Ruby
run: |
source $HOME/.rvm/scripts/rvm
rvm install ${{ matrix.ruby }} --disable-binary
rvm --default use ${{ matrix.ruby }}
- name: Build
run: |
source $HOME/.rvm/scripts/rvm
sudo apt-get install libcurl4-openssl-dev
gem install bundler -v '<2'
bundle install --jobs 4 --retry 3
- name: Test
run: |
source $HOME/.rvm/scripts/rvm
bundle exec rake

29
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Publish
on:
release:
types: [published]
jobs:
build:
name: Publish to Rubygems
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
version: 2.6.x
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build faraday.gemspec
gem push faraday-*.gem
env:
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}

4
.gitignore vendored
View File

@ -1,7 +1,6 @@
## PROJECT::GENERAL
coverage
rdoc
doc
log
pkg/*
tmp
@ -20,3 +19,6 @@ vendor/bundle
## IDEs
.idea/
# master branch only!
docs

3
.rspec Normal file
View File

@ -0,0 +1,3 @@
--require spec_helper
--format documentation
--color

View File

@ -1,47 +0,0 @@
sudo: false
language: ruby
script: bundle exec script/test
cache: bundler
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- 2.3
- 2.4
- 2.5.0
- ruby-head
- jruby-19mode
- jruby-20mode
- jruby-21mode
- jruby-head
matrix:
allow_failures:
# "A fatal error has been detected by the Java Runtime Environment:
# Internal Error (sharedRuntime.cpp:843)"
- rvm: jruby-19mode
- rvm: jruby-20mode
- rvm: jruby-21mode
- rvm: jruby-head
- rvm: ruby-head
fast_finish: true
env:
matrix:
- SSL=no
- SSL=yes
global:
- JRUBY_OPTS="$JRUBY_OPTS --debug"
deploy:
provider: rubygems
api_key:
secure: EqbOu9BQp5jkivJ8qvTo89f3J49KOByBueU3XulrJ2Kqm/ov4RDFsmp9/uHAnSLdmKSkzZaeq79t1AUNfKGX1ZqkKgq/Nw2BKGFnh5ZOjrkrRZR1Vm09OHxqiViEbtg+jZ8VOLY/iDFEkNIzuj9/H3iHGXC0XiKH2LTHOFH63Bs=
gem: faraday
on:
tags: true
repo: lostisland/faraday
rvm: 2.4
condition: '"$SSL" = "yes"'

View File

@ -1,6 +1,216 @@
# Faraday Changelog
For newer changes, please see https://github.com/lostisland/faraday/releases
## v0.17.3
Fixes:
* Reverts changes in error classes hierarchy. #1092 (@iMacTia)
* Fix Ruby 1.9 syntax errors and improve Error class testing #1094 (@BanzaiMan,
@mrexox, @technoweenie)
Misc:
* Stops using `&Proc.new` for block forwarding. #1083 (@olleolleolle)
* Update CI to test against ruby 2.0-2.7 #1087, #1099 (@iMacTia, @olleolleolle,
@technoweenie)
* require FARADAY_DEPRECATE=warn to show Faraday v1.0 deprecation warnings
#1098 (@technoweenie)
## v0.17.1
Final release before Faraday v1.0, with important fixes for Ruby 2.7.
Fixes:
* RaiseError response middleware raises exception if HTTP client returns a nil
status. #1042 (@jonnyom, @BobbyMcWho)
Misc:
* Fix Ruby 2.7 warnings (#1009)
* Add `Faraday::Deprecate` to warn about upcoming v1.0 changes. (#1054, #1059,
#1076, #1077)
* Add release notes up to current in CHANGELOG.md (#1066)
* Port minimal rspec suite from main branch to run backported tests. (#1058)
## v0.17.0
This release is the same as v0.15.4. It was pushed to cover up releases
v0.16.0-v0.16.2.
## v0.15.4
* Expose `pool_size` as a option for the NetHttpPersistent adapter (#834)
## v0.15.3
* Make Faraday::Request serialisable with Marshal. (#803)
* Add DEFAULT_EXCEPTIONS constant to Request::Retry (#814)
* Add support for Ruby 2.6 Net::HTTP write_timeout (#824)
## v0.15.2
* Prevents `Net::HTTP` adapters to retry request internally by setting `max_retries` to 0 if available (Ruby 2.5+). (#799)
* Fixes `NestedParamsEncoder` handling of empty array values (#801)
## v0.15.1
* NetHttpPersistent adapter better reuse of SSL connections (#793)
* Refactor: inline cached_connection (#797)
* Logger middleware: use $stdout instead of STDOUT (#794)
* Fix: do not memoize/reuse Patron session (#796)
Also in this release:
* Allow setting min/max ssl version for Net::HTTP (#792)
* Allow setting min/max ssl version for Excon (#795)
## v0.15.0
Features:
* Added retry block option to retry middleware. (#770)
* Retry middleware improvements (honour Retry-After header, retry statuses) (#773)
* Improve response logger middleware output (#784)
Fixes:
* Remove unused class error (#767)
* Fix minor typo in README (#760)
* Reuse persistent connections when using net-http-persistent (#778)
* Fix Retry middleware documentation (#781)
* Returns the http response when giving up on retrying by status (#783)
## v0.14.0
Features:
* Allow overriding env proxy (#754)
* Remove legacy Typhoeus adapter (#715)
* External Typhoeus Adapter Compatibility (#748)
* Warn about missing adapter when making a request (#743)
* Faraday::Adapter::Test stubs now support entire urls (with host) (#741)
Fixes:
* If proxy is manually provided, this takes priority over `find_proxy` (#724)
* Fixes the behaviour for Excon's open_timeout (not setting write_timeout anymore) (#731)
* Handle all connection timeout messages in Patron (#687)
## v0.13.1
* Fixes an incompatibility with Addressable::URI being used as uri_parser
## v0.13.0
Features:
* Dynamically reloads the proxy when performing a request on an absolute domain (#701)
* Adapter support for Net::HTTP::Persistent v3.0.0 (#619)
Fixes:
* Prefer #hostname over #host. (#714)
* Fixes an edge-case issue with response headers parsing (missing HTTP header) (#719)
## v0.12.2
* Parse headers from aggregated proxy requests/responses (#681)
* Guard against invalid middleware configuration with warning (#685)
* Do not use :insecure option by default in Patron (#691)
* Fixes an issue with HTTPClient not raising a `Faraday::ConnectionFailed` (#702)
* Fixes YAML serialization/deserialization for `Faraday::Utils::Headers` (#690)
* Fixes an issue with Options having a nil value (#694)
* Fixes an issue with Faraday.default_connection not using Faraday.default_connection_options (#698)
* Fixes an issue with Options.merge! and Faraday instrumentation middleware (#710)
## v0.12.1
* Fix an issue with Patron tests failing on jruby
* Fix an issue with new `rewind_files` feature that was causing an exception when the body was not an Hash
* Expose wrapped_exception in all client errors
* Add Authentication Section to the ReadMe
## v0.12.0.1
* Hotfix release to address an issue with TravisCI deploy on Rubygems
## v0.12.0
Features:
* Proxy feature now relies on Ruby `URI::Generic#find_proxy` and can use `no_proxy` ENV variable (not compatible with ruby < 2.0)
* Adds support for `context` request option to pass arbitrary information to middlewares
Fixes:
* Fix an issue with options that was causing new options to override defaults ones unexpectedly
* Rewind `UploadIO`s on retry to fix a compatibility issue
* Make multipart boundary unique
* Improvements in `README.md`
## v0.11.0
Features:
* Add `filter` method to Logger middleware
* Add support for Ruby2.4 and Minitest 6
* Introduce block syntax to customise the adapter
Fixes:
* Fix an issue that was allowing to override `default_connection_options` from a connection instance
* Fix a bug that was causing newline escape characters ("\n") to be used when building the Authorization header
## v0.10.1
- Fix an issue with HTTPClient adapter that was causing the SSL to be reset on every request
- Rescue `IOError` instead of specific subclass
- `Faraday::Utils::Headers` can now be successfully serialised in YAML
- Handle `default_connection_options` set with hash
## v0.10.0
Breaking changes:
- Drop support for Ruby 1.8
Features:
- Include wrapped exception/reponse in ClientErrors
- Add `response.reason_phrase`
- Provide option to selectively skip logging request/response headers
- Add regex support for pattern matching in `test` adapter
Fixes:
- Add `Faraday.respond_to?` to find methods managed by `method_missing`
- em-http: `request.host` instead of `connection.host` should be taken for SSL validations
- Allow `default_connection_options` to be merged when options are passed as url parameter
- Improve splitting key-value pairs in raw HTTP headers
## v0.9.2
Adapters:
- Enable gzip compression for httpclient
- Fixes default certificate store for httpclient not having default paths.
- Make excon adapter compatible with 0.44 excon version
- Add compatibility with Patron 0.4.20
- Determine default port numbers in Net::HTTP adapters (Addressable compatibility)
- em-http: wrap "connection closed by server" as ConnectionFailed type
- Wrap Errno::ETIMEDOUT in Faraday::Error::TimeoutError
Utils:
- Add Rack-compatible support for parsing `a[][b]=c` nested queries
- Encode nil values in queries different than empty strings. Before: `a=`; now: `a`.
- Have `Faraday::Utils::Headers#replace` clear internal key cache
- Dup the internal key cache when a Headers hash is copied
Env and middleware:
- Ensure `env` stored on middleware response has reference to the response
- Ensure that Response properties are initialized during `on_complete` (VCR compatibility)
- Copy request options in Faraday::Connection#dup
- Env custom members should be copied by Env.from(env)
- Honour per-request `request.options.params_encoder`
- Fix `interval_randomness` data type for Retry middleware
- Add maximum interval option for Retry middleware
## v0.9.1

13
Gemfile
View File

@ -4,7 +4,16 @@ ruby RUBY_VERSION
gem 'ffi-ncurses', '~> 0.3', :platforms => :jruby
gem 'jruby-openssl', '~> 0.8.8', :platforms => :jruby
gem 'rake'
if RUBY_VERSION > '2'
gem 'net-http-persistent', group: :test
gem 'rake'
gem 'tins'
else
gem 'net-http-persistent', '< 3.0', group: :test
gem 'rake', '= 12.2.1'
gem 'tins', '= 1.6.0'
end
group :test do
gem 'coveralls', :require => false
@ -15,10 +24,10 @@ group :test do
gem 'httpclient', '>= 2.2'
gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
gem 'minitest', '>= 5.0.5'
gem 'net-http-persistent'
gem 'patron', '>= 0.4.2', :platforms => :ruby
gem 'rack-test', '>= 0.6', :require => 'rack/test'
gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18]
gem 'rspec', '~> 3.7'
gem 'simplecov'
gem 'sinatra', '~> 1.3'
gem 'typhoeus', '~> 1.3', :require => 'typhoeus'

View File

@ -1,7 +1,7 @@
# Faraday
[![Gem Version](https://badge.fury.io/rb/faraday.svg)](https://rubygems.org/gems/faraday)
[![Build Status](https://travis-ci.org/lostisland/faraday.svg)](https://travis-ci.org/lostisland/faraday)
[![Build Status](https://travis-ci.org/lostisland/faraday.svg?branch=master)](https://travis-ci.org/lostisland/faraday)
[![Coverage Status](https://coveralls.io/repos/github/lostisland/faraday/badge.svg?branch=master)](https://coveralls.io/github/lostisland/faraday?branch=master)
[![Code Climate](https://codeclimate.com/github/lostisland/faraday/badges/gpa.svg)](https://codeclimate.com/github/lostisland/faraday)
[![Gitter](https://badges.gitter.im/lostisland/faraday.svg)](https://gitter.im/lostisland/faraday?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
@ -31,6 +31,17 @@ Rack::Test, and a Test adapter for stubbing requests by hand.
Available at [rubydoc.info](http://www.rubydoc.info/gems/faraday).
## Faraday 1.0
Faraday 1.0 will ship soon! Faraday 0.17 will be the last 0.x release, except for serious bugs or security issues.
Faraday 1.0 is a major release, but it will be mostly backwards-compatible with 0.x, so we strongly encourage you
to use it on your next projects and/or consider to upgrade your existing ones.
Upgrading is simple:
* Checkout the new code from [`master`](https://github.com/lostisland/faraday) and the new [Documentation Website](https://lostisland.github.io/faraday/).
* If you're upgrading an existing project, check the [UPGRADING](https://github.com/lostisland/faraday/blob/master/UPGRADING.md) file.
* You can also enable upgrade warnings on apps with Faraday 0.x if you run them with `FARADAY_DEPRECATE=warn` or `FARADAY_DEPRECATE=1` in ENV.
## Usage
### Basic Use
@ -189,6 +200,9 @@ Faraday.new(...) do |conn|
# POST/PUT params encoders:
conn.request :multipart
conn.request :url_encoded
# add custom middleware
conn.use MyMiddleware
# Last middleware must be the adapter:
conn.adapter :net_http

View File

@ -1,8 +1,13 @@
# frozen_string_literal: true
require 'rake/testtask'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :default => :test
desc "Run all tests"
task :test do
task :test => :spec do
exec 'script/test'
end

View File

@ -9,14 +9,20 @@ Gem::Specification.new do |spec|
spec.summary = "HTTP/REST API client library."
spec.authors = ["Rick Olson"]
spec.authors = ["@technoweenie", "@iMacTia", "@olleolleolle"]
spec.email = 'technoweenie@gmail.com'
spec.homepage = 'https://github.com/lostisland/faraday'
spec.homepage = 'https://lostisland.github.io/faraday'
spec.licenses = ['MIT']
spec.required_ruby_version = '>= 1.9'
spec.add_dependency 'multipart-post', '>= 1.2', '< 3'
spec.files = `git ls-files -z lib LICENSE.md README.md`.split("\0")
spec.files = `git ls-files -z CHANGELOG.md LICENSE.md README.md Rakefile lib test spec`.split("\0")
spec.metadata = {
"homepage_uri" => "https://lostisland.github.io/faraday",
"changelog_uri" => "https://github.com/lostisland/faraday/blob/master/CHANGELOG.md",
"source_code_uri" => "https://github.com/lostisland/faraday/",
"bug_tracker_uri" => "https://github.com/lostisland/faraday/issues"
}
end

View File

@ -14,7 +14,7 @@ require 'forwardable'
# conn.get '/'
#
module Faraday
VERSION = "0.15.3"
VERSION = "0.17.4"
class << self
# Public: Gets or sets the root path that Faraday is being loaded from.
@ -64,8 +64,7 @@ module Faraday
# :params => {:page => 1}
#
# Returns a Faraday::Connection.
def new(url = nil, options = nil)
block = block_given? ? Proc.new : nil
def new(url = nil, options = nil, &block)
options = options ? default_connection_options.merge(options) : default_connection_options
Faraday::Connection.new(url, options, &block)
end

View File

@ -124,9 +124,9 @@ module Faraday
end
rescue EventMachine::Connectify::CONNECTError => err
if err.message.include?("Proxy Authentication Required")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue => err
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
@ -159,15 +159,15 @@ module Faraday
end
def raise_error(msg)
errklass = Faraday::Error::ClientError
errklass = Faraday::ClientError
if msg == Errno::ETIMEDOUT
errklass = Faraday::Error::TimeoutError
errklass = Faraday::TimeoutError
msg = "request timed out"
elsif msg == Errno::ECONNREFUSED
errklass = Faraday::Error::ConnectionFailed
errklass = Faraday::ConnectionFailed
msg = "connection refused"
elsif msg == "connection closed by server"
errklass = Faraday::Error::ConnectionFailed
errklass = Faraday::ConnectionFailed
end
raise errklass, msg
end
@ -193,11 +193,11 @@ module Faraday
def running?() @running end
def add
def add(&block)
if running?
perform_request { yield }
else
@registered_procs << Proc.new
@registered_procs << block
end
@num_registered += 1
end
@ -211,7 +211,7 @@ module Faraday
end
end
if @errors.size > 0
raise Faraday::Error::ClientError, @errors.first || "connection failed"
raise Faraday::ClientError, @errors.first || "connection failed"
end
end
ensure

View File

@ -65,18 +65,18 @@ module Faraday
@app.call env
rescue Errno::ECONNREFUSED
raise Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
rescue EventMachine::Connectify::CONNECTError => err
if err.message.include?("Proxy Authentication Required")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue Errno::ETIMEDOUT => err
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
rescue RuntimeError => err
if err.message == "connection closed by server"
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
else
raise
end

View File

@ -59,14 +59,14 @@ module Faraday
@app.call env
rescue ::Excon::Errors::SocketError => err
if err.message =~ /\btimeout\b/
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
elsif err.message =~ /\bcertificate\b/
raise Faraday::SSLError, err
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
rescue ::Excon::Errors::Timeout => err
raise Error::TimeoutError, err
raise Faraday::TimeoutError, err
end
def create_connection(env, opts)

View File

@ -43,15 +43,15 @@ module Faraday
@app.call env
rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
raise Faraday::Error::TimeoutError, $!
raise Faraday::TimeoutError, $!
rescue ::HTTPClient::BadResponseError => err
if err.message.include?('status 407')
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Faraday::Error::ClientError, $!
raise Faraday::ClientError, $!
end
rescue Errno::ECONNREFUSED, IOError, SocketError
raise Faraday::Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
rescue => err
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
raise Faraday::SSLError, err

View File

@ -11,6 +11,7 @@ module Faraday
class NetHttp < Faraday::Adapter
NET_HTTP_EXCEPTIONS = [
IOError,
Errno::EADDRNOTAVAIL,
Errno::ECONNABORTED,
Errno::ECONNREFUSED,
Errno::ECONNRESET,
@ -45,7 +46,7 @@ module Faraday
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
raise Faraday::SSLError, err
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
end
@ -58,7 +59,7 @@ module Faraday
@app.call env
rescue Timeout::Error, Errno::ETIMEDOUT => err
raise Faraday::Error::TimeoutError, err
raise Faraday::TimeoutError, err
end
private

View File

@ -10,7 +10,7 @@ module Faraday
if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
options = {name: 'Faraday'}
options[:pool_size] = @connection_options[:pool_size] if @connection_options.key?(:pool_size)
Net::HTTP::Persistent.new(options)
Net::HTTP::Persistent.new(**options)
else
Net::HTTP::Persistent.new('Faraday')
end
@ -37,12 +37,12 @@ module Faraday
def perform_request(http, env)
http.request env[:url], create_request(env)
rescue Errno::ETIMEDOUT => error
raise Faraday::Error::TimeoutError, error
raise Faraday::TimeoutError, error
rescue Net::HTTP::Persistent::Error => error
if error.message.include? 'Timeout'
raise Faraday::Error::TimeoutError, error
raise Faraday::TimeoutError, error
elsif error.message.include? 'connection refused'
raise Faraday::Error::ConnectionFailed, error
raise Faraday::ConnectionFailed, error
else
raise
end

View File

@ -28,7 +28,7 @@ module Faraday
data = env[:body] ? env[:body].to_s : nil
session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
raise Error::ConnectionFailed, $!
raise Faraday::ConnectionFailed, $!
end
# Remove the "HTTP/1.1 200", leaving just the reason phrase
@ -39,15 +39,15 @@ module Faraday
@app.call env
rescue ::Patron::TimeoutError => err
if connection_timed_out_message?(err.message)
raise Faraday::Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
else
raise Faraday::Error::TimeoutError, err
raise Faraday::TimeoutError, err
end
rescue ::Patron::Error => err
if err.message.include?("code 407")
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
else
raise Error::ConnectionFailed, err
raise Faraday::ConnectionFailed, err
end
end

View File

@ -41,7 +41,7 @@ module Faraday
timeout = env[:request][:timeout] || env[:request][:open_timeout]
response = if timeout
Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
Timer.timeout(timeout, Faraday::TimeoutError) { execute_request(env, rack_env) }
else
execute_request(env, rack_env)
end

109
lib/faraday/deprecate.rb Normal file
View File

@ -0,0 +1,109 @@
# frozen_string_literal: true
module Faraday
# @param new_klass [Class] new Klass to use
#
# @return [Class] A modified version of new_klass that warns on
# usage about deprecation.
# @see Faraday::Deprecate
module DeprecatedClass
def self.proxy_class(origclass, ver = '1.0')
proxy = Class.new(origclass) do
const_set("ORIG_CLASS", origclass)
class << self
extend Faraday::Deprecate
def ===(other)
(superclass == const_get("ORIG_CLASS") && other.is_a?(superclass)) || super
end
end
end
proxy.singleton_class.send(:deprecate, :new, "#{origclass}.new", ver)
proxy.singleton_class.send(:deprecate, :inherited, origclass.name, ver)
proxy
end
end
# Deprecation using semver instead of date, based on Gem::Deprecate
# Provides a single method +deprecate+ to be used to declare when
# something is going away.
#
# class Legacy
# def self.klass_method
# # ...
# end
#
# def instance_method
# # ...
# end
#
# extend Faraday::Deprecate
# deprecate :instance_method, "X.z", '1.0'
#
# class << self
# extend Faraday::Deprecate
# deprecate :klass_method, :none, '1.0'
# end
# end
module Deprecate
def self.skip # :nodoc:
@skip ||= begin
case ENV['FARADAY_DEPRECATE'].to_s.downcase
when '1', 'warn' then :warn
else :skip
end
end
@skip == :skip
end
def self.skip=(value) # :nodoc:
@skip = value ? :skip : :warn
end
# Temporarily turn off warnings. Intended for tests only.
def skip_during
original = Faraday::Deprecate.skip
Faraday::Deprecate.skip, = true
yield
ensure
Faraday::Deprecate.skip = original
end
# Simple deprecation method that deprecates +name+ by wrapping it up
# in a dummy method. It warns on each call to the dummy method
# telling the user of +repl+ (unless +repl+ is :none) and the
# semver that it is planned to go away.
# @param name [Symbol] the method symbol to deprecate
# @param repl [#to_s, :none] the replacement to use, when `:none` it will
# alert the user that no replacemtent is present.
# @param ver [String] the semver the method will be removed.
def deprecate(name, repl, ver)
class_eval do
gem_ver = Gem::Version.new(ver)
old = "_deprecated_#{name}"
alias_method old, name
define_method name do |*args, &block|
mod = is_a? Module
target = mod ? "#{self}." : "#{self.class}#"
target_message = if name == :inherited
"Inheriting #{self}"
else
"#{target}#{name}"
end
msg = [
"NOTE: #{target_message} is deprecated",
repl == :none ? ' with no replacement' : "; use #{repl} instead. ",
"It will be removed in or after version #{gem_ver}",
"\n#{target}#{name} called from #{Gem.location_of_caller.join(':')}"
]
warn "#{msg.join}." unless Faraday::Deprecate.skip
send old, *args, &block
end
end
end
module_function :deprecate, :skip_during
end
end

View File

@ -1,22 +1,17 @@
module Faraday
class Error < StandardError; end
# frozen_string_literal: true
class ClientError < Error
require 'faraday/deprecate'
# Faraday namespace.
module Faraday
# Faraday error base class.
class Error < StandardError
attr_reader :response, :wrapped_exception
def initialize(ex, response = nil)
@wrapped_exception = nil
@response = response
if ex.respond_to?(:backtrace)
super(ex.message)
@wrapped_exception = ex
elsif ex.respond_to?(:each_key)
super("the server responded with status #{ex[:status]}")
@response = ex
else
super(ex.to_s)
end
def initialize(exc, response = nil)
@wrapped_exception = nil unless defined?(@wrapped_exception)
@response = nil unless defined?(@response)
super(exc_msg_and_response!(exc, response))
end
def backtrace
@ -29,38 +24,135 @@ module Faraday
def inspect
inner = ''
if @wrapped_exception
inner << " wrapped=#{@wrapped_exception.inspect}"
end
if @response
inner << " response=#{@response.inspect}"
end
if inner.empty?
inner << " #{super}"
end
inner += " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
inner += " response=#{@response.inspect}" if @response
inner += " #{super}" if inner.empty?
%(#<#{self.class}#{inner}>)
end
end
class ConnectionFailed < ClientError; end
class ResourceNotFound < ClientError; end
class ParsingError < ClientError; end
protected
class TimeoutError < ClientError
def initialize(ex = nil)
super(ex || "timeout")
# Pulls out potential parent exception and response hash, storing them in
# instance variables.
# exc - Either an Exception, a string message, or a response hash.
# response - Hash
# :status - Optional integer HTTP response status
# :headers - String key/value hash of HTTP response header
# values.
# :body - Optional string HTTP response body.
#
# If a subclass has to call this, then it should pass a string message
# to `super`. See NilStatusError.
def exc_msg_and_response!(exc, response = nil)
if @response.nil? && @wrapped_exception.nil?
@wrapped_exception, msg, @response = exc_msg_and_response(exc, response)
return msg
end
exc.to_s
end
# Pulls out potential parent exception and response hash.
def exc_msg_and_response(exc, response = nil)
return [exc, exc.message, response] if exc.respond_to?(:backtrace)
return [nil, "the server responded with status #{exc[:status]}", exc] \
if exc.respond_to?(:each_key)
[nil, exc.to_s, response]
end
end
# Faraday client error class. Represents 4xx status responses.
class ClientError < Error
end
# Raised by Faraday::Response::RaiseError in case of a 400 response.
class BadRequestError < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 401 response.
class UnauthorizedError < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 403 response.
class ForbiddenError < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 404 response.
class ResourceNotFound < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 407 response.
class ProxyAuthError < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 409 response.
class ConflictError < ClientError
end
# Raised by Faraday::Response::RaiseError in case of a 422 response.
class UnprocessableEntityError < ClientError
end
# Faraday server error class. Represents 5xx status responses.
class ServerError < Error
end
# A unified client error for timeouts.
class TimeoutError < ClientError
def initialize(exc = 'timeout', response = nil)
super(exc, response)
end
end
# Raised by Faraday::Response::RaiseError in case of a nil status in response.
class NilStatusError < ServerError
def initialize(exc, response = nil)
exc_msg_and_response!(exc, response)
@response = unwrap_resp!(@response)
super('http status could not be derived from the server response')
end
private
extend Faraday::Deprecate
def unwrap_resp(resp)
if inner = (resp.keys.size == 1 && resp[:response])
return unwrap_resp(inner)
end
resp
end
alias_method :unwrap_resp!, :unwrap_resp
deprecate('unwrap_resp', nil, '1.0')
end
# A unified error for failed connections.
class ConnectionFailed < ClientError
end
# A unified client error for SSL errors.
class SSLError < ClientError
end
class RetriableResponse < ClientError; end
[:ClientError, :ConnectionFailed, :ResourceNotFound,
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
Error.const_set(const, Faraday.const_get(const))
# Raised by FaradayMiddleware::ResponseMiddleware
class ParsingError < ClientError
end
# Exception used to control the Retry middleware.
#
# @see Faraday::Request::Retry
class RetriableResponse < ClientError
end
[:ClientError, :ConnectionFailed, :ResourceNotFound,
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
Error.const_set(
const,
DeprecatedClass.proxy_class(Faraday.const_get(const))
)
end
end

View File

@ -72,7 +72,7 @@ module Faraday
if args.size > 0
send(key_setter, args.first)
elsif block_given?
send(key_setter, Proc.new.call(key))
send(key_setter, yield(key))
else
raise self.class.fetch_error_class, "key not found: #{key.inspect}"
end
@ -162,8 +162,8 @@ module Faraday
@attribute_options ||= {}
end
def self.memoized(key)
memoized_attributes[key.to_sym] = Proc.new
def self.memoized(key, &block)
memoized_attributes[key.to_sym] = block
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{key}() self[:#{key}]; end
RUBY

View File

@ -49,10 +49,10 @@ module Faraday
end
end
def initialize(handlers = [])
def initialize(handlers = [], &block)
@handlers = handlers
if block_given?
build(&Proc.new)
build(&block)
elsif @handlers.empty?
# default stack, if nothing else is configured
self.request :url_encoded

View File

@ -1,3 +1,5 @@
require 'date'
module Faraday
# Catches exceptions and retries each request a limited number of times.
#
@ -19,8 +21,9 @@ module Faraday
# interval that is random between 0.1 and 0.15
#
class Request::Retry < Faraday::Middleware
DEFAULT_EXCEPTIONS = [Errno::ETIMEDOUT, 'Timeout::Error', Error::TimeoutError, Faraday::Error::RetriableResponse].freeze
DEFAULT_EXCEPTIONS = [Errno::ETIMEDOUT, 'Timeout::Error',
Faraday::TimeoutError, Faraday::RetriableResponse
].freeze
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
class Options < Faraday::Options.new(:max, :interval, :max_interval, :interval_randomness,
@ -93,7 +96,7 @@ module Faraday
# exceptions - The list of exceptions to handle. Exceptions can be
# given as Class, Module, or String. (default:
# [Errno::ETIMEDOUT, 'Timeout::Error',
# Error::TimeoutError, Faraday::Error::RetriableResponse])
# Faraday::TimeoutError, Faraday::RetriableResponse])
# methods - A list of HTTP methods to retry without calling retry_if. Pass
# an empty Array to call retry_if for all exceptions.
# (defaults to the idempotent HTTP methods in IDEMPOTENT_METHODS)
@ -126,7 +129,7 @@ module Faraday
begin
env[:body] = request_body # after failure env[:body] is set to the response body
@app.call(env).tap do |resp|
raise Faraday::Error::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
end
rescue @errmatch => exception
if retries > 0 && retry_request?(env, exception)
@ -139,7 +142,7 @@ module Faraday
end
end
if exception.is_a?(Faraday::Error::RetriableResponse)
if exception.is_a?(Faraday::RetriableResponse)
exception.response
else
raise

View File

@ -54,9 +54,9 @@ module Faraday
!!env
end
def on_complete
if not finished?
@on_complete_callbacks << Proc.new
def on_complete(&block)
if !finished?
@on_complete_callbacks << block
else
yield(env)
end

View File

@ -5,12 +5,16 @@ module Faraday
def on_complete(env)
case env[:status]
when 404
raise Faraday::Error::ResourceNotFound, response_values(env)
raise Faraday::ResourceNotFound, response_values(env)
when 407
# mimic the behavior that we get with proxy requests with HTTPS
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
raise Faraday::ConnectionFailed.new(
%{407 "Proxy Authentication Required "},
response_values(env))
when ClientErrorStatuses
raise Faraday::Error::ClientError, response_values(env)
raise Faraday::ClientError, response_values(env)
when nil
raise Faraday::NilStatusError, response_values(env)
end
end

View File

@ -0,0 +1,147 @@
# frozen_string_literal: true
RSpec.describe Faraday::DeprecatedClass do
class SampleClass < StandardError
attr_accessor :foo
def initialize(foo = nil)
@foo = foo || :foo
end
end
SampleDeprecatedClass = Faraday::DeprecatedClass.proxy_class(SampleClass)
it 'does not raise error for deprecated classes but prints an error message' do
error_message, foobar = with_warn_squelching { SampleDeprecatedClass.new(:foo_bar) }
expect(foobar).to be_a(SampleClass)
expect(foobar.foo).to eq(:foo_bar)
expect(error_message).to match(
Regexp.new(
'NOTE: SampleDeprecatedClass.new is deprecated; '\
'use SampleClass.new instead. It will be removed in or after version 1.0'
)
)
end
it 'does not raise an error for inherited error-namespaced classes but prints an error message' do
error_message, = with_warn_squelching { Class.new(SampleDeprecatedClass) }
expect(error_message).to match(
Regexp.new(
'NOTE: Inheriting SampleDeprecatedClass is deprecated; '\
'use SampleClass instead. It will be removed in or after version 1.0'
)
)
end
it 'allows backward-compatible class to be subclassed' do
expect {
with_warn_squelching { Class.new(SampleDeprecatedClass) }
}.not_to raise_error
end
it 'allows rescuing of a current error with a deprecated error' do
expect { raise SampleClass, nil }.to raise_error(SampleDeprecatedClass)
end
it 'allows rescuing of a current error with a current error' do
expect { raise SampleClass, nil }.to raise_error(SampleClass)
end
it 'allows rescuing of a deprecated error with a deprecated error' do
expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleDeprecatedClass)
end
it 'allows rescuing of a deprecated error with a current error' do
expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleClass)
end
describe 'match behavior' do
class SampleDeprecatedClassA < SampleDeprecatedClass; end
class SampleDeprecatedClassB < SampleDeprecatedClass; end
class SampleDeprecatedClassAX < SampleDeprecatedClassA; end
class SampleClassA < SampleClass; end
describe 'undeprecated class' do
it 'is === to instance of deprecated class' do
expect(SampleClass === SampleDeprecatedClass.new).to be true
end
it 'is === to instance of subclass of deprecated class' do
expect(SampleClass === SampleDeprecatedClassA.new).to be true
end
it 'is === to instance of subclass of subclass of deprecated class' do
expect(SampleClass === SampleDeprecatedClassAX.new).to be true
end
end
describe 'subclass of undeprecated class' do
it 'is not === to instance of undeprecated class' do
expect(SampleClassA === SampleClass.new).to be false
end
it 'is not === to instance of deprecated class' do
expect(SampleClassA === SampleDeprecatedClass.new).to be false
end
end
describe 'deprecated class' do
it 'is === to instance of undeprecated class' do
expect(SampleDeprecatedClass === SampleClass.new).to be true
end
it 'is === to instance of subclass of undeprecated class' do
expect(SampleDeprecatedClass === SampleClassA.new).to be true
end
it 'is === to instance of subclass of deprecated class' do
expect(SampleDeprecatedClass === SampleDeprecatedClassA.new).to be true
end
it 'is === to instance of subclass of subclass of deprecated class' do
expect(SampleDeprecatedClass === SampleDeprecatedClassAX.new).to be true
end
end
describe 'subclass of deprecated class' do
it 'is not === to instance of subclass of undeprecated class' do
expect(SampleDeprecatedClassA === SampleClass.new).to be false
end
it 'is not === to instance of another subclass of deprecated class' do
expect(SampleDeprecatedClassA === SampleDeprecatedClassB.new).to be false
end
it 'is === to instance of its subclass' do
expect(SampleDeprecatedClassA === SampleDeprecatedClassAX.new).to be true
end
it 'is === to instance of deprecated class' do
expect(SampleDeprecatedClass === SampleDeprecatedClassB.new).to be true
end
end
describe 'subclass of subclass of deprecated class' do
it 'is not === to instance of subclass of another subclass of deprecated class' do
expect(SampleDeprecatedClassAX === SampleDeprecatedClassB.new).to be false
end
it 'is not === to instance of its superclass' do
expect(SampleDeprecatedClassA === SampleDeprecatedClass.new).to be false
end
end
end
def with_warn_squelching
stderr_catcher = StringIO.new
original_stderr = $stderr
$stderr = stderr_catcher
result = yield if block_given?
[stderr_catcher.tap(&:rewind).string, result]
ensure
$stderr = original_stderr
end
end

102
spec/faraday/error_spec.rb Normal file
View File

@ -0,0 +1,102 @@
# frozen_string_literal: true
RSpec.describe Faraday::ClientError do
describe '.initialize' do
subject { described_class.new(exception, response) }
let(:response) { nil }
context 'with exception only' do
let(:exception) { RuntimeError.new('test') }
it { expect(subject.wrapped_exception).to eq(exception) }
it { expect(subject.response).to be_nil }
it { expect(subject.message).to eq(exception.message) }
it { expect(subject.backtrace).to eq(exception.backtrace) }
it { expect(subject.inspect).to eq('#<Faraday::ClientError wrapped=#<RuntimeError: test>>') }
end
context 'with response hash' do
let(:exception) { { status: 400 } }
it { expect(subject.wrapped_exception).to be_nil }
it { expect(subject.response).to eq(exception) }
it { expect(subject.message).to eq('the server responded with status 400') }
it { expect(subject.inspect).to eq('#<Faraday::ClientError response={:status=>400}>') }
end
context 'with string' do
let(:exception) { 'custom message' }
it { expect(subject.wrapped_exception).to be_nil }
it { expect(subject.response).to be_nil }
it { expect(subject.message).to eq('custom message') }
it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: custom message>>') }
end
context 'with anything else #to_s' do
let(:exception) { %w[error1 error2] }
it { expect(subject.wrapped_exception).to be_nil }
it { expect(subject.response).to be_nil }
it { expect(subject.message).to eq('["error1", "error2"]') }
it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: ["error1", "error2"]>>') }
end
context 'maintains backward-compatibility until 1.0' do
it 'does not raise an error for error-namespaced classes but prints an error message' do
error_message, error = with_warn_squelching { Faraday::Error::ClientError.new('foo') }
expect(error).to be_a Faraday::ClientError
expect(error_message).to match(
Regexp.new(
'NOTE: Faraday::Error::ClientError.new is deprecated; '\
'use Faraday::ClientError.new instead. It will be removed in or after version 1.0'
)
)
end
it 'does not raise an error for inherited error-namespaced classes but prints an error message' do
error_message, = with_warn_squelching { Class.new(Faraday::Error::ClientError) }
expect(error_message).to match(
Regexp.new(
'NOTE: Inheriting Faraday::Error::ClientError is deprecated; '\
'use Faraday::ClientError instead. It will be removed in or after version 1.0'
)
)
end
it 'allows backward-compatible class to be subclassed' do
expect {
with_warn_squelching { Class.new(Faraday::Error::ClientError) }
}.not_to raise_error
end
it 'allows rescuing of a current error with a deprecated error' do
expect { raise Faraday::ClientError, nil }.to raise_error(Faraday::Error::ClientError)
end
it 'allows rescuing of a current error with a current error' do
expect { raise Faraday::ClientError, nil }.to raise_error(Faraday::ClientError)
end
it 'allows rescuing of a deprecated error with a deprecated error' do
expect { raise Faraday::Error::ClientError, nil }.to raise_error(Faraday::Error::ClientError)
end
it 'allows rescuing of a deprecated error with a current error' do
expect { raise Faraday::Error::ClientError, nil }.to raise_error(Faraday::ClientError)
end
end
def with_warn_squelching
stderr_catcher = StringIO.new
original_stderr = $stderr
$stderr = stderr_catcher
result = yield if block_given?
[stderr_catcher.tap(&:rewind).string, result]
ensure
$stderr = original_stderr
end
end
end

View File

@ -0,0 +1,106 @@
# frozen_string_literal: true
RSpec.describe Faraday::Response::RaiseError do
let(:conn) do
Faraday.new do |b|
b.response :raise_error
b.adapter :test do |stub|
stub.get('ok') { [200, { 'Content-Type' => 'text/html' }, '<body></body>'] }
stub.get('bad-request') { [400, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('unauthorized') { [401, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('forbidden') { [403, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('not-found') { [404, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('proxy-error') { [407, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('conflict') { [409, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('unprocessable-entity') { [422, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('4xx') { [499, { 'X-Reason' => 'because' }, 'keep looking'] }
stub.get('nil-status') { [nil, { 'X-Reason' => 'nil' }, 'fail'] }
stub.get('server-error') { [500, { 'X-Error' => 'bailout' }, 'fail'] }
end
end
end
it 'raises no exception for 200 responses' do
expect { conn.get('ok') }.not_to raise_error
end
it 'raises Faraday::ClientError for 400 responses' do
expect { conn.get('bad-request') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 400')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(400)
end
end
it 'raises Faraday::ClientError for 401 responses' do
expect { conn.get('unauthorized') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 401')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(401)
end
end
it 'raises Faraday::ClientError for 403 responses' do
expect { conn.get('forbidden') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 403')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(403)
end
end
it 'raises Faraday::ResourceNotFound for 404 responses' do
expect { conn.get('not-found') }.to raise_error(Faraday::ResourceNotFound) do |ex|
expect(ex.message).to eq('the server responded with status 404')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(404)
end
end
it 'raises Faraday::ConnectionFailed for 407 responses' do
expect { conn.get('proxy-error') }.to raise_error(Faraday::ConnectionFailed) do |ex|
expect(ex.message).to eq('407 "Proxy Authentication Required "')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(407)
end
end
it 'raises Faraday::ClientError for 409 responses' do
expect { conn.get('conflict') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 409')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(409)
end
end
it 'raises Faraday::ClientError for 422 responses' do
expect { conn.get('unprocessable-entity') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 422')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(422)
end
end
it 'raises Faraday::NilStatusError for nil status in response' do
expect { conn.get('nil-status') }.to raise_error(Faraday::NilStatusError) do |ex|
expect(ex.message).to eq('http status could not be derived from the server response')
expect(ex.response[:headers]['X-Reason']).to eq('nil')
expect(ex.response[:status]).to be_nil
end
end
it 'raises Faraday::ClientError for other 4xx responses' do
expect { conn.get('4xx') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 499')
expect(ex.response[:headers]['X-Reason']).to eq('because')
expect(ex.response[:status]).to eq(499)
end
end
it 'raises Faraday::ClientError for 500 responses' do
expect { conn.get('server-error') }.to raise_error(Faraday::ClientError) do |ex|
expect(ex.message).to eq('the server responded with status 500')
expect(ex.response[:headers]['X-Error']).to eq('bailout')
expect(ex.response[:status]).to eq(500)
end
end
end

105
spec/spec_helper.rb Normal file
View File

@ -0,0 +1,105 @@
# frozen_string_literal: true
require 'faraday'
Faraday::Deprecate.skip = false
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
# defined using `chain`, e.g.:
# be_bigger_than(2).and_smaller_than(4).description
# # => "be bigger than 2 and smaller than 4"
# ...rather than:
# # => "be bigger than 2"
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
# rspec-mocks config goes here. You can use an alternate test double
# library (such as bogus or mocha) by changing the `mock_with` option here.
config.mock_with :rspec do |mocks|
# Prevents you from mocking or stubbing a method that does not exist on
# a real object. This is generally recommended, and will default to
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
# have no way to turn it off -- the option exists only for backwards
# compatibility in RSpec 3). It causes shared context metadata to be
# inherited by the metadata hash of host groups and examples, rather than
# triggering implicit auto-inclusion in groups with matching metadata.
config.shared_context_metadata_behavior = :apply_to_host_groups
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
# Limits the available syntax to the non-monkey patched syntax that is
# recommended. For more details, see:
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
config.disable_monkey_patching!
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
=begin
# This allows you to limit a spec run to individual examples or groups
# you care about by tagging them with `:focus` metadata. When nothing
# is tagged with `:focus`, all examples get run. RSpec also provides
# aliases for `it`, `describe`, and `context` that include `:focus`
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
config.filter_run_when_matching :focus
# Allows RSpec to persist some state between runs in order to support
# the `--only-failures` and `--next-failure` CLI options. We recommend
# you configure your source control system to ignore this file.
config.example_status_persistence_file_path = "spec/examples.txt"
# This setting enables warnings. It's recommended, but in some cases may
# be too noisy due to issues in dependencies.
config.warnings = true
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = "doc"
end
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
=end
end

View File

@ -180,13 +180,13 @@ module Adapters
def test_timeout
conn = create_connection(:request => {:timeout => 1, :open_timeout => 1})
assert_raises Faraday::Error::TimeoutError do
assert_raises Faraday::TimeoutError do
conn.get '/slow'
end
end
def test_connection_error
assert_raises Faraday::Error::ConnectionFailed do
assert_raises Faraday::ConnectionFailed do
get 'http://localhost:4'
end
end
@ -209,7 +209,7 @@ module Adapters
proxy_uri.password = 'WRONG'
conn = create_connection(:proxy => proxy_uri)
err = assert_raises Faraday::Error::ConnectionFailed do
err = assert_raises Faraday::ConnectionFailed do
conn.get '/echo'
end

View File

@ -31,7 +31,7 @@ module Adapters
def test_connection_timeout
conn = create_connection(:request => {:timeout => 10, :open_timeout => 1})
assert_raises Faraday::Error::ConnectionFailed do
assert_raises Faraday::ConnectionFailed do
conn.get 'http://8.8.8.8:88'
end
end

View File

@ -26,7 +26,7 @@ module Adapters
conn = create_connection(:request => {:timeout => 1, :open_timeout => 1})
begin
conn.get '/slow'
rescue Faraday::Error::ClientError
rescue Faraday::TimeoutError
end
end

View File

@ -23,7 +23,7 @@ class ResponseMiddlewareTest < Faraday::TestCase
end
def test_raises_not_found
error = assert_raises Faraday::Error::ResourceNotFound do
error = assert_raises Faraday::ResourceNotFound do
@conn.get('not-found')
end
assert_equal 'the server responded with status 404', error.message
@ -31,7 +31,7 @@ class ResponseMiddlewareTest < Faraday::TestCase
end
def test_raises_error
error = assert_raises Faraday::Error::ClientError do
error = assert_raises Faraday::ClientError do
@conn.get('error')
end
assert_equal 'the server responded with status 500', error.message