restful_error 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +68 -59
- data/app/views/layouts/application.html.erb +5 -0
- data/app/views/restful_error/show.json.ruby +5 -0
- data/lib/restful_error/application_controller.rb +11 -0
- data/lib/restful_error/exceptions_app.rb +44 -0
- data/lib/restful_error/exceptions_controller.rb +19 -0
- data/lib/restful_error/railtie.rb +10 -22
- data/lib/restful_error/version.rb +1 -1
- data/lib/restful_error.rb +11 -11
- metadata +7 -3
- data/app/views/restful_error/show.json.erb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed208c312dae52e3f02f31f16ee66ebe34b6a98f02195c6dae1178c8ae638aab
|
4
|
+
data.tar.gz: f28848072ce6af1819ccefce94b474c11d5eb92543698f5fb4478d80984cc6a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 833c5516e492850176e4321769fd2eb4060036b2948c9a9bcbbe40bace7c082bb4f473879713c02ba55a204509214bd57f50963128a384e16db23586c710519a
|
7
|
+
data.tar.gz: ed25e5a04a3ddb4761449d034b2457097c7d7aa2a4a684dfcaa9a4dccd211c9baecd7d54e1dc3460fac03501eb8a49c5ed32751a6bc96f6353336e7fa2f67e4e
|
data/README.md
CHANGED
@@ -16,41 +16,65 @@ And then execute:
|
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
### Pure ruby
|
19
|
+
### Pure ruby (without Rails)
|
20
|
+
#### Predefined errors
|
20
21
|
```ruby
|
21
22
|
ex = RestfulError[404].new
|
22
|
-
|
23
|
-
ex
|
23
|
+
|
24
|
+
StandardError === ex # => true # because inherit from StandardError
|
25
|
+
RestfulError::BaseError === ex # => true
|
26
|
+
|
27
|
+
RestfulError[404] == RestfulError::NotFound # => true # same class
|
28
|
+
|
29
|
+
ex.status_data # returns Data about status code
|
30
|
+
# => #<data RestfulError::Status
|
31
|
+
# code=404,
|
32
|
+
# reason_phrase="Not Found",
|
33
|
+
# symbol=:not_found,
|
34
|
+
# const_name="NotFound">
|
35
|
+
ex.status_data.code # => 404
|
24
36
|
```
|
25
37
|
|
26
|
-
####
|
38
|
+
#### Custom error by subclassing
|
27
39
|
```ruby
|
28
40
|
class ::NoSession < RestfulError[404]; end
|
29
41
|
# or
|
30
42
|
class ::NoSession < RestfulError::NotFound; end
|
31
43
|
```
|
32
|
-
#### your custom error with http_status
|
33
|
-
```ruby
|
34
|
-
class OAuthController < ApplicationController
|
35
44
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# or
|
42
|
-
class PermissionError < StandardError
|
43
|
-
include RestfulError::Helper
|
44
|
-
def http_status; :unauthorized; end
|
45
|
-
end
|
45
|
+
#### Custom error with http_status
|
46
|
+
```ruby
|
47
|
+
# define http_status and include RestfulError::Helper
|
48
|
+
class User::PermissionError < StandardError
|
49
|
+
include RestfulError::Helper
|
50
|
+
def http_status = :unauthorized # or 401
|
46
51
|
end
|
47
|
-
PermissionError.new.
|
52
|
+
User::PermissionError.new.status_data.reason_phrase # => "Unauthorized"
|
53
|
+
```
|
54
|
+
|
55
|
+
### With I18n
|
56
|
+
`#response_message` returns i18nized message.
|
57
|
+
```yaml
|
58
|
+
ja:
|
59
|
+
restful_error:
|
60
|
+
unauthorized: ログインが必要です
|
61
|
+
not_found: ページが存在しません
|
62
|
+
user/permission_error: 権限がありません
|
63
|
+
```
|
64
|
+
```ruby
|
65
|
+
# lookup class name first, then status symbol
|
66
|
+
User::PermissionError.new.response_message # => "権限がありません"
|
67
|
+
AnotherPermissionError.new.response_message # => "ログインが必要です"
|
48
68
|
```
|
49
69
|
|
50
70
|
### With Rails
|
51
|
-
`config.exceptions_app` will automatically set.
|
71
|
+
`config.exceptions_app` will automatically set to RestfulError::ExceptionsApp.
|
72
|
+
|
73
|
+
If you want to disable it, you have two options.
|
74
|
+
- `config.restful_error.exceptions_app.enable = false` (will not set exceptions_app)
|
75
|
+
- `config.exceptions_app = ActionDispatch::PublicExceptions.new(Rails.public_path)` (set Rails default explicitly, or set your own)
|
52
76
|
|
53
|
-
####
|
77
|
+
#### Raise me in request handling
|
54
78
|
```ruby
|
55
79
|
class PostsController < ApplicationController
|
56
80
|
before_action do
|
@@ -62,58 +86,43 @@ end
|
|
62
86
|
```
|
63
87
|
|
64
88
|
|
65
|
-
####
|
89
|
+
#### Render response
|
90
|
+
Default view files are in https://github.com/kuboon/restful_error/tree/main/app/views/restful_error
|
66
91
|
|
67
|
-
|
68
|
-
get '/posts/new'
|
69
|
-
#=> render 'restful_error/show.html' with @status_code and @message
|
92
|
+
`html`, `json` and `xml` are supported.
|
70
93
|
|
71
|
-
|
72
|
-
#=> { status_code: 401, message: "Sign in required" } or write your json at 'restful_error/show.json'
|
94
|
+
You can override them by creating view file `show.{format}.{handler}` under your `app/views/restful_error/` directory.
|
73
95
|
|
74
|
-
|
75
|
-
#=> "<error><status_code type="integer">401</status_code><message>Sign in required</message></error>" or write your xml at 'restful_error/show.xml'
|
76
|
-
```
|
96
|
+
`@status` `@status_code` `@reason_phrase` `@response_message` are available in the view.
|
77
97
|
|
78
|
-
|
98
|
+
If you have `layouts/restful_error.*.*`, or `layouts/application.*.*`, it will be used as layout. This is done by inheriting `::ApplicationController`.
|
79
99
|
|
80
|
-
|
81
|
-
|
82
|
-
restful_error:
|
83
|
-
unauthorized: ログインしてください #401
|
84
|
-
not_found: ページが存在しません #404
|
85
|
-
```
|
100
|
+
To change superclass,
|
101
|
+
set `config.restful_error.exceptions_app.inherit_from = 'AnotherBaseController'`
|
86
102
|
|
87
|
-
####
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
config.action_dispatch.rescue_responses["
|
103
|
+
#### Library defined error
|
104
|
+
You can assign status code to error classes which are not yours. (This is Rails standard)
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :unauthorized # or 401
|
92
108
|
```
|
93
|
-
|
109
|
+
|
110
|
+
RestfulError will use this configuration to lookup status code and
|
111
|
+
`@response_message` will be set.
|
112
|
+
|
94
113
|
```yaml
|
95
114
|
ja:
|
96
115
|
restful_error:
|
97
|
-
|
98
|
-
oauth_controller/require_twitter_login: Twitterログインが必要です
|
99
|
-
can_can/unauthorized: 権限がありません
|
116
|
+
pundit/not_authorized_error: アクセス権限がありません
|
100
117
|
active_record/record_not_found: 要求されたリソースが存在しません
|
101
118
|
```
|
102
|
-
#### custom message
|
103
119
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
:unauthorized
|
111
|
-
end
|
112
|
-
def response_message
|
113
|
-
I18n.t('restful_error.require_login', provider: provider)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
```
|
120
|
+
## Why `response_message`, not `message`?
|
121
|
+
`StandardError#message` is used for debugging purpose, not intended to be shown to users.
|
122
|
+
Rails default behavior does not show `message` in production environment. So I decided to use `response_message` instead.
|
123
|
+
|
124
|
+
You can `def response_message` or set `@resposne_message` in your error class to build dynamic message.
|
125
|
+
|
117
126
|
|
118
127
|
## Contributing
|
119
128
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "abstract_controller"
|
2
|
+
require "action_controller/metal"
|
3
|
+
|
4
|
+
module RestfulError
|
5
|
+
class ApplicationController < ::ActionController::Metal
|
6
|
+
abstract!
|
7
|
+
include AbstractController::Rendering
|
8
|
+
include ActionView::Layouts
|
9
|
+
include ActionController::Rendering
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "abstract_controller"
|
2
|
+
require "action_controller/metal"
|
3
|
+
|
4
|
+
module RestfulError
|
5
|
+
class ExceptionsApp
|
6
|
+
Config = Struct.new(:enable, :inherit_from, :fallback)
|
7
|
+
def self.config
|
8
|
+
@config ||= Config.new.tap do |config|
|
9
|
+
config.enable = true
|
10
|
+
config.inherit_from = "::ApplicationController"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(config = self.class.config)
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
def call(env)
|
18
|
+
app.call(env)
|
19
|
+
rescue Exception => _e
|
20
|
+
raise unless @config.fallback
|
21
|
+
@config.fallback.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def app
|
27
|
+
@app ||= begin
|
28
|
+
# To use "layouts/application" we need inherit from ::ApplicationController
|
29
|
+
# It is not defined at config time, so we need to load it here
|
30
|
+
if @config.inherit_from && Object.const_defined?(@config.inherit_from)
|
31
|
+
inherit_from = @config.inherit_from.constantize
|
32
|
+
else
|
33
|
+
inherit_from = RestfulError::ApplicationController
|
34
|
+
end
|
35
|
+
const_set_without_warn(RestfulError, "SuperController", inherit_from)
|
36
|
+
ExceptionsController.action(:show)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def const_set_without_warn(klass, const_name, value)
|
40
|
+
klass.send(:remove_const, const_name) if klass.const_defined?(const_name)
|
41
|
+
klass.const_set(const_name, value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RestfulError
|
2
|
+
class ExceptionsController < SuperController
|
3
|
+
def self.controller_path = "restful_error"
|
4
|
+
append_view_path File.join(File.dirname(__FILE__), "../../app/views")
|
5
|
+
|
6
|
+
layout nil
|
7
|
+
|
8
|
+
def show
|
9
|
+
@exception = request.env["action_dispatch.exception"]
|
10
|
+
code = request.path_info[1..].to_i
|
11
|
+
status = RestfulError.build_status_from_symbol_or_code(code)
|
12
|
+
@status_code = status.code
|
13
|
+
@reason_phrase = status.reason_phrase
|
14
|
+
@response_message = @exception.try(:response_message) || RestfulError.localized_phrase(@exception.class.name, status) || nil
|
15
|
+
|
16
|
+
render status: status.code, formats: request.format.symbol
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,27 +1,15 @@
|
|
1
|
-
require "
|
2
|
-
require "action_controller/metal"
|
1
|
+
require "restful_error/exceptions_app"
|
3
2
|
|
4
3
|
module RestfulError
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
status = RestfulError.build_status_from_symbol_or_code(code)
|
15
|
-
@status_code = status.code
|
16
|
-
@reason_phrase = status.reason_phrase
|
17
|
-
@response_message = @exception.try(:response_message) || RestfulError.localized_phrase(@exception.class.name, status) || nil
|
18
|
-
|
19
|
-
self.status = status.code
|
20
|
-
render "restful_error/show", formats: request.format.symbol
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
config.restful_error = ActiveSupport::OrderedOptions.new
|
6
|
+
config.restful_error.exceptions_app = RestfulError::ExceptionsApp.config
|
7
|
+
|
8
|
+
initializer "restful_error.exceptions_app", before: :build_middleware_stack do |app|
|
9
|
+
if app.config.restful_error.exceptions_app.enable
|
10
|
+
app.config.restful_error.exceptions_app.fallback ||= ActionDispatch::PublicExceptions.new(Rails.public_path)
|
11
|
+
app.config.exceptions_app ||= RestfulError::ExceptionsApp.new
|
12
|
+
end
|
21
13
|
end
|
22
14
|
end
|
23
|
-
|
24
|
-
def self.exceptions_app
|
25
|
-
ExceptionsController.action(:show)
|
26
|
-
end
|
27
15
|
end
|
data/lib/restful_error.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rack/utils"
|
4
|
-
require "restful_error/railtie" if defined? ActionController
|
5
4
|
require "restful_error/status"
|
6
5
|
require "restful_error/version"
|
6
|
+
require "restful_error/railtie" if defined? Rails::Railtie
|
7
7
|
|
8
8
|
module RestfulError
|
9
|
+
autoload :ExceptionsApp, "restful_error/exceptions_app"
|
10
|
+
autoload :ApplicationController, "restful_error/application_controller"
|
11
|
+
autoload :ExceptionsController, "restful_error/exceptions_controller"
|
12
|
+
|
9
13
|
module Helper
|
10
|
-
def
|
11
|
-
@
|
12
|
-
raise NotImplementedError, "http_status must be implemented by including class" unless respond_to?(:http_status)
|
13
|
-
RestfulError.build_status_from_symbol_or_code(http_status)
|
14
|
-
end
|
14
|
+
def status_data
|
15
|
+
@status_data ||= RestfulError.build_status_from_symbol_or_code(http_status)
|
15
16
|
end
|
16
17
|
def response_message
|
17
18
|
return @response_message unless @response_message.nil?
|
18
|
-
@response_message = RestfulError.localized_phrase(self.class.name,
|
19
|
+
@response_message = RestfulError.localized_phrase(self.class.name, status_data)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
class BaseError < StandardError
|
23
24
|
include RestfulError::Helper
|
24
|
-
def
|
25
|
-
|
26
|
-
super
|
25
|
+
def http_status
|
26
|
+
raise NotImplementedError, "http_status must be implemented"
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -58,7 +58,7 @@ module RestfulError
|
|
58
58
|
def build_error_class_for(status)
|
59
59
|
klass = Class.new(BaseError) do
|
60
60
|
define_method(:http_status) { status.code }
|
61
|
-
define_method(:
|
61
|
+
define_method(:status_data) { status }
|
62
62
|
end
|
63
63
|
const_set(status.const_name, klass)
|
64
64
|
if defined? ActionDispatch::ExceptionWrapper
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restful_error
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kuboon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -40,12 +40,16 @@ extra_rdoc_files: []
|
|
40
40
|
files:
|
41
41
|
- LICENSE.txt
|
42
42
|
- README.md
|
43
|
+
- app/views/layouts/application.html.erb
|
43
44
|
- app/views/restful_error/show.html.erb
|
44
|
-
- app/views/restful_error/show.json.
|
45
|
+
- app/views/restful_error/show.json.ruby
|
45
46
|
- app/views/restful_error/show.xml.erb
|
46
47
|
- config/locales/en.restful_error.yml
|
47
48
|
- config/locales/ja.restful_error.yml
|
48
49
|
- lib/restful_error.rb
|
50
|
+
- lib/restful_error/application_controller.rb
|
51
|
+
- lib/restful_error/exceptions_app.rb
|
52
|
+
- lib/restful_error/exceptions_controller.rb
|
49
53
|
- lib/restful_error/inflector.rb
|
50
54
|
- lib/restful_error/railtie.rb
|
51
55
|
- lib/restful_error/status.rb
|