From 28b00dc6fc4f9903c7bd0d4a84aabee1b4391e74 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Mon, 1 Nov 2021 16:38:41 +1000 Subject: [PATCH] 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 ' # ./spec/rails_helper.rb:280:in `block (2 levels) in ' ``` 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 ' # ./spec/rails_helper.rb:280:in `block (2 levels) in ' # ------------------ # --- 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 --- spec/rails_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 61523bc2d7e..1a68ce59bb7 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