Class: Utopia::Redirection::Errors

Inherits:
Protocol::HTTP::Middleware
  • Object
show all
Defined in:
lib/utopia/redirection/errors.rb

Overview

A middleware which performs internal redirects based on error status codes.

Place this middleware after client-visible redirection middleware in the application configuration. Internal error-document requests invoke the delegate directly, bypassing middleware configured before this one.

Instance Method Summary collapse

Constructor Details

#initialize(app, codes = {}) ⇒ Errors

Returns a new instance of Errors.

Parameters:

  • codes (Hash<Integer,String>) (defaults to: {})

    The redirection path for a given error code.



20
21
22
23
24
# File 'lib/utopia/redirection/errors.rb', line 20

def initialize(app, codes = {})
	super(app)
	
	@codes = codes
end

Instance Method Details

#call(request) ⇒ Object

Replace an unhandled error response with its configured error document.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/utopia/redirection/errors.rb', line 47

def call(request)
	response = Response.wrap(@delegate.call(request))
	
	if unhandled_error?(response) && location = @codes[response.status]
		resource_status = response.status
		
		# The original response is replaced by the configured error document:
		response.close
		
		error_request = request.with(method: "GET", path: location)
		
		error_response = Response.wrap(@delegate.call(error_request))
		
		if error_response.status >= 400
			error = RequestFailure.new(request.url.path.encoded, resource_status, location, error_response.status)
			
			# The failed error document will not be returned to the server:
			error_response.close(error)
			
			raise error
		else
			# Feed the error code back with the error document:
			error_response.status = resource_status
			return error_response
		end
	else
		return response
	end
end

#freezeObject

Freeze this object and its internal state.



28
29
30
31
32
33
34
# File 'lib/utopia/redirection/errors.rb', line 28

def freeze
	return self if frozen?
	
	@codes.freeze
	
	super
end

#unhandled_error?(response) ⇒ Boolean

Check whether the response status requires error handling.

Returns:

  • (Boolean)


39
40
41
# File 'lib/utopia/redirection/errors.rb', line 39

def unhandled_error?(response)
	response.status >= 400 && response.headers.empty?
end