rails_react_errors 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7ef71a095ca3fcaef5dc57a2add11dd13dea5c088226c4561957a93d72f7be5
4
- data.tar.gz: 43401d67835cddd1ad89efeafefc0f91eb8b10671c36060832d5ec1cb5693d1c
3
+ metadata.gz: ac6abfaf6c7bcfb5c7b9e363ecf4385e313043b48b9a6c488f1d618a8dcab77d
4
+ data.tar.gz: 4af4ffa98d1d3b4e9d64064e5a10f10f28ffc86ccfd10be4aeb61c309b37ae2f
5
5
  SHA512:
6
- metadata.gz: 5f032bd5f67b6c8938cc07a3d0d173cc973e2c834687829703e7402eda367bd0fa30f475d0b1994b0a3bdd58659a242fe2654bc1b8fa0dc584209bcffdba9543
7
- data.tar.gz: 5c3b634d195ab8bc05be86366cfa5ab85d5fd7c9476dbfacc3c0f010ab3ce55cfcc2239da30d186b585f568314d123d1794a2c68289448b8c3c75ce7254227ae
6
+ metadata.gz: 8e73812697af09fdc076ae881e55dfab37969d1a90e6b75d59546e08fa3b34e4d4183dcde978a1452cdc6b1b621b74dabf666cb28d1034a758eb62a95e2d9d78
7
+ data.tar.gz: dd7cd735f7cc112029b4d5434dfbe8a0d2a2f0fc03bf06bc09144d6d72ad187d730ddfd2fbafe0e140276971c05ca9d2847e0bdf45634d608f71680e1073b0b4
data/README.md CHANGED
@@ -1,74 +1,187 @@
1
- # RailsReactErrors
1
+ # rails_react_errors
2
+
3
+ Consistent error responses for **Rails APIs used by React frontends**.
4
+
5
+ `rails_react_errors` standardizes API error responses so React applications can easily handle validation errors, authentication errors, and server failures.
2
6
 
3
- TODO: Delete this and the text below, and describe your gem
7
+ Instead of handling multiple Rails error formats, this gem provides a **single predictable JSON structure**.
4
8
 
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rails_react_errors`. To experiment with that code, run `bin/console` for an interactive prompt.
9
+ ---
6
10
 
7
11
  ## Installation
8
12
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem "rails_react_errors"
17
+ ```
10
18
 
11
- Install the gem and add to the application's Gemfile by executing:
19
+ Then run:
12
20
 
13
21
  ```bash
14
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
22
+ bundle install
15
23
  ```
16
24
 
17
- If bundler is not being used to manage dependencies, install the gem by executing:
25
+ ---
18
26
 
19
- ```bash
20
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
27
+ ## Quick Setup
28
+
29
+ Include the controller module in your base controller.
30
+
31
+ ```ruby
32
+ class ApplicationController < ActionController::API
33
+ include RailsReactErrors::Controller
34
+ end
21
35
  ```
22
36
 
23
- ## Usage
37
+ That's it. Your Rails API will now automatically return standardized error responses.
24
38
 
25
- TODO: Write usage instructions here
39
+ ---
26
40
 
27
- ## Development
41
+ ## Automatic Exception Handling
28
42
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
43
+ The gem automatically handles common Rails exceptions and converts them into consistent JSON responses.
30
44
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
45
+ Supported exceptions:
32
46
 
33
- ## Contributing
47
+ * `ActiveRecord::RecordNotFound`
48
+ * `ActiveRecord::RecordInvalid`
49
+ * `ActiveRecord::RecordNotUnique`
50
+ * `ActionController::ParameterMissing`
51
+ * `JSON::ParserError`
52
+ * `StandardError` *(optional)*
34
53
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rails_react_errors. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/rails_react_errors/blob/master/CODE_OF_CONDUCT.md).
54
+ Example:
36
55
 
37
- ## License
56
+ ```ruby
57
+ class UsersController < ApplicationController
58
+ def show
59
+ user = User.find(params[:id])
60
+ render json: user
61
+ end
62
+ end
63
+ ```
38
64
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
65
+ If the record does not exist:
40
66
 
41
- ## Code of Conduct
67
+ ```json
68
+ {
69
+ "success": false,
70
+ "message": "Couldn't find User with 'id'=99",
71
+ "code": "NOT_FOUND",
72
+ "errors": {}
73
+ }
74
+ ```
42
75
 
43
- Everyone interacting in the RailsReactErrors project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rails_react_errors/blob/master/CODE_OF_CONDUCT.md).
76
+ ---
44
77
 
45
- # rails_react_errors
78
+ ## Validation Error Example
46
79
 
47
- Consistent error responses for Rails APIs used by React frontends.
80
+ ```ruby
81
+ class UsersController < ApplicationController
82
+ def create
83
+ user = User.create!(user_params)
84
+ render json: { success: true, data: user }, status: :created
85
+ end
86
+
87
+ private
88
+
89
+ def user_params
90
+ params.require(:user).permit(:email, :password)
91
+ end
92
+ end
93
+ ```
48
94
 
49
- ## Installation
95
+ Response:
96
+
97
+ ```json
98
+ {
99
+ "success": false,
100
+ "message": "Validation failed",
101
+ "code": "VALIDATION_ERROR",
102
+ "errors": {
103
+ "email": ["Email can't be blank"]
104
+ }
105
+ }
106
+ ```
50
107
 
51
- ## Usage
108
+ ---
52
109
 
53
- ## Validation Errors
110
+ ## JSON Parsing Error
54
111
 
55
- ## Not Found Errors
112
+ If an invalid JSON payload is sent:
56
113
 
57
- ## Unauthorized Errors
114
+ ```json
115
+ { email: "test"
116
+ ```
58
117
 
59
- ## Configuration
118
+ Response:
60
119
 
61
- ## React Example
120
+ ```json
121
+ {
122
+ "success": false,
123
+ "message": "Invalid JSON payload",
124
+ "code": "INVALID_JSON",
125
+ "errors": {}
126
+ }
127
+ ```
62
128
 
63
- ## Contributing
129
+ ---
64
130
 
65
- # rails_react_errors
131
+ ## Available Helper Methods
66
132
 
67
- Consistent error responses for Rails APIs used by React frontends.
133
+ You can also manually render errors if needed.
68
134
 
69
- ## Installation
135
+ ```ruby
136
+ render_validation_error(record)
137
+ render_not_found_error("User not found")
138
+ render_parameter_missing_error("param is missing")
139
+ render_conflict_error("Duplicate record")
140
+ render_server_error("Something went wrong")
141
+ render_error(message:, code:, status:, errors: {})
142
+ ```
70
143
 
71
- Add this line to your application's Gemfile:
144
+ ---
145
+
146
+ ## Custom Exception Mapping
147
+
148
+ You can configure your own exceptions.
72
149
 
73
150
  ```ruby
74
- gem "rails_react_errors"
151
+ RailsReactErrors.configure do |config|
152
+ config.custom_exceptions = {
153
+ "Pundit::NotAuthorizedError" => {
154
+ code: "FORBIDDEN",
155
+ status: :forbidden
156
+ },
157
+ "JWT::DecodeError" => {
158
+ code: "INVALID_TOKEN",
159
+ status: :unauthorized
160
+ }
161
+ }
162
+ end
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Enable Global Error Handling
168
+
169
+ To automatically handle unexpected errors:
170
+
171
+ ```ruby
172
+ RailsReactErrors.configure do |config|
173
+ config.rescue_standard_error = true
174
+ end
175
+ ```
176
+
177
+ ---
178
+
179
+ ## License
180
+
181
+ MIT License
182
+
183
+ ---
184
+
185
+ ## Author
186
+
187
+ Manish Prajapati
@@ -4,12 +4,14 @@ module RailsReactErrors
4
4
  class Configuration
5
5
  attr_accessor :include_full_messages,
6
6
  :rescue_standard_error,
7
- :log_errors
7
+ :log_errors,
8
+ :custom_exceptions
8
9
 
9
10
  def initialize
10
11
  @include_full_messages = true
11
12
  @rescue_standard_error = false
12
13
  @log_errors = true
14
+ @custom_exceptions = {}
13
15
  end
14
16
  end
15
17
  end
@@ -9,10 +9,31 @@ module RailsReactErrors
9
9
  base.rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found
10
10
  end
11
11
 
12
+ if defined?(ActiveRecord::RecordInvalid)
13
+ base.rescue_from ActiveRecord::RecordInvalid, with: :handle_record_invalid
14
+ end
15
+
12
16
  if defined?(ActionController::ParameterMissing)
13
17
  base.rescue_from ActionController::ParameterMissing, with: :handle_parameter_missing
14
18
  end
15
19
 
20
+ base.rescue_from ActiveRecord::RecordNotUnique, with: :handle_conflict if defined?(ActiveRecord::RecordNotUnique)
21
+
22
+ base.rescue_from JSON::ParserError, with: :handle_invalid_json if defined?(JSON::ParserError)
23
+
24
+ RailsReactErrors.configuration.custom_exceptions.each do |klass, config|
25
+ exception_class = Object.const_get(klass)
26
+ base.rescue_from exception_class do |exception|
27
+ render_error(
28
+ message: exception.message,
29
+ code: config[:code],
30
+ status: config[:status]
31
+ )
32
+ end
33
+ rescue NameError
34
+ next
35
+ end
36
+
16
37
  return unless RailsReactErrors.configuration.rescue_standard_error
17
38
 
18
39
  base.rescue_from StandardError, with: :handle_internal_server_error
@@ -24,13 +45,20 @@ module RailsReactErrors
24
45
  render_not_found_error(exception.message)
25
46
  end
26
47
 
48
+ def handle_record_invalid(exception)
49
+ render_validation_error(exception.record)
50
+ end
51
+
27
52
  def handle_parameter_missing(exception)
28
- render json: {
29
- success: false,
30
- message: exception.message,
31
- code: 'PARAMETER_MISSING',
32
- errors: {}
33
- }, status: :bad_request
53
+ render_parameter_missing_error(exception.message)
54
+ end
55
+
56
+ def handle_conflict(exception)
57
+ render_conflict_error(exception.message)
58
+ end
59
+
60
+ def handle_invalid_json(_exception)
61
+ render_invalid_json_error('Invalid JSON payload')
34
62
  end
35
63
 
36
64
  def handle_internal_server_error(exception)
@@ -22,6 +22,18 @@ module RailsReactErrors
22
22
  render json: RailsReactErrors::Serializer.server_error(message), status: status
23
23
  end
24
24
 
25
+ def render_parameter_missing_error(message, status: :bad_request)
26
+ render json: RailsReactErrors::Serializer.parameter_missing(message), status: status
27
+ end
28
+
29
+ def render_conflict_error(message, status: :conflict)
30
+ render json: RailsReactErrors::Serializer.conflict(message), status: status
31
+ end
32
+
33
+ def render_invalid_json_error(message = 'Invalid JSON payload', status: :bad_request)
34
+ render json: RailsReactErrors::Serializer.invalid_json(message), status: status
35
+ end
36
+
25
37
  def render_error(message:, code:, status:, errors: {})
26
38
  render json: {
27
39
  success: false,
@@ -22,6 +22,18 @@ module RailsReactErrors
22
22
  new.server_error(message)
23
23
  end
24
24
 
25
+ def self.parameter_missing(message)
26
+ new.parameter_missing(message)
27
+ end
28
+
29
+ def self.conflict(message = 'Conflict')
30
+ new.conflict(message)
31
+ end
32
+
33
+ def self.invalid_json(message = 'Invalid JSON payload')
34
+ new.invalid_json(message)
35
+ end
36
+
25
37
  def validation(record)
26
38
  {
27
39
  success: false,
@@ -67,6 +79,33 @@ module RailsReactErrors
67
79
  }
68
80
  end
69
81
 
82
+ def parameter_missing(message)
83
+ {
84
+ success: false,
85
+ message: message,
86
+ code: 'PARAMETER_MISSING',
87
+ errors: {}
88
+ }
89
+ end
90
+
91
+ def conflict(message)
92
+ {
93
+ success: false,
94
+ message: message,
95
+ code: 'CONFLICT',
96
+ errors: {}
97
+ }
98
+ end
99
+
100
+ def invalid_json(message)
101
+ {
102
+ success: false,
103
+ message: message,
104
+ code: 'INVALID_JSON',
105
+ errors: {}
106
+ }
107
+ end
108
+
70
109
  private
71
110
 
72
111
  def serialized_errors(record)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsReactErrors
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_react_errors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manish0407
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-03-06 00:00:00.000000000 Z
11
+ date: 2026-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel