DEV: Output webmock errors in request specs (#14782)

DEV: Output webmock errors in request specs (#14782)

  • DEV: Output webmock errors in request specs

In request specs, if you had not properly mocked an external HTTP call, you would end up with a 500 error with no further information instead of your expected response code, with an rspec output like this:

Failures:

  1) UploadsController#generate_presigned_put when the store is external generates a presigned URL and creates an external upload stub
     Failure/Error: expect(response.status).to eq(200)

       expected: 200
            got: 500

       (compared using ==)
     # ./spec/requests/uploads_controller_spec.rb:727:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:280:in `block (2 levels) in <top (required)>'

This is not helpful at all when you want to find what you actually failed to mock, which is shown straight away in non-request specs.

This commit introduces a rescue_from block in the application controller to log this error, so we have a much nicer output that helps the developer find the issue:

Failures:

  1) UploadsController#generate_presigned_put when the store is external generates a presigned URL and creates an external upload stub
     Failure/Error: expect(response.status).to eq(200)

       expected: 200
            got: 500

       (compared using ==)
     # ./spec/requests/uploads_controller_spec.rb:727:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:280:in `block (2 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # WebMock::NetConnectNotAllowedError:
     #   Real HTTP connections are disabled. Unregistered request: GET https://s3-upload-bucket.s3.us-west-1.amazonaws.com/?cors with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'', 'Authorization'=>'AWS4-HMAC-SHA256 Credential=some key/20211101/us-west-1/s3/aws4_request, SignedHeaders=host;user-agent;x-amz-content-sha256;x-amz-date, Signature=test', 'Host'=>'s3-upload-bucket.s3.us-west-1.amazonaws.com', 'User-Agent'=>'aws-sdk-ruby3/3.121.2 ruby/2.7.1 x86_64-linux aws-sdk-s3/1.96.1', 'X-Amz-Content-Sha256'=>'test', 'X-Amz-Date'=>'20211101T035113Z'}
     #
     #   You can stub this request with the following snippet:
     #
     #   stub_request(:get, "https://s3-upload-bucket.s3.us-west-1.amazonaws.com/?cors").
     #     with(
     #       headers: {
     #   	  'Accept'=>'*/*',
     #   	  'Accept-Encoding'=>'',
     #   	  'Authorization'=>'AWS4-HMAC-SHA256 Credential=some key/20211101/us-west-1/s3/aws4_request, SignedHeaders=host;user-agent;x-amz-content-sha256;x-amz-date, Signature=test',
     #   	  'Host'=>'s3-upload-bucket.s3.us-west-1.amazonaws.com',
     #   	  'User-Agent'=>'aws-sdk-ruby3/3.121.2 ruby/2.7.1 x86_64-linux aws-sdk-s3/1.96.1',
     #   	  'X-Amz-Content-Sha256'=>'test',
     #   	  'X-Amz-Date'=>'20211101T035113Z'
     #       }).
     #     to_return(status: 200, body: "", headers: {})
     #
     #   registered request stubs:
     #
     #   stub_request(:head, "https://s3-upload-bucket.s3.us-west-1.amazonaws.com/")
     #
     #   ============================================================
  • DEV: Require webmock in application controller if rails.env.test

  • DEV: Rescue from StandardError and NetConnectNotAllowedError

diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 61523bc..1a68ce5 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -44,7 +44,11 @@ class RspecErrorTracker
   def call(env)
     begin
       @app.call(env)
-    rescue => e
+
+    # This is a little repetitive, but since WebMock::NetConnectNotAllowedError
+    # inherits from Exception instead of StandardError it does not get captured
+    # by the rescue => e shorthand :(
+    rescue WebMock::NetConnectNotAllowedError, StandardError => e
       RspecErrorTracker.last_exception = e
       raise e
     end

GitHub sha: 28b00dc6fc4f9903c7bd0d4a84aabee1b4391e74

This commit appears in #14782 which was approved by tgxworld. It was merged by tgxworld.