templates/app/lib/plug_app/middleware/openapi_validation.rb in hephaestus-0.6.0 vs templates/app/lib/plug_app/middleware/openapi_validation.rb in hephaestus-0.6.1

- old
+ new

@@ -10,45 +10,74 @@ SPEC_PATH = Rails.root.join("lib/plug_app/schemas/api/2023-03-06/openapi.json") SPEC = OpenapiFirst.load(SPEC_PATH) def initialize(app) @app = app - @response_validator = OpenapiFirst::ResponseValidator.new(SPEC) - @request_validator = OpenapiFirst::RequestValidation.new(->(_env) {}, spec: SPEC, raise_error: true) end def call(env) request = Rack::Request.new(env) - if request.path.starts_with?(API_PATH_PREFIX) + return @app.call(env) unless request.path.starts_with?(API_PATH_PREFIX) && request.path.exclude?("/settings") + + begin # force content-type to JSON - if env["CONTENT_TYPE"] == "application/x-www-form-urlencoded" - env["CONTENT_TYPE"] = "application/json" - end + env["CONTENT_TYPE"] = "application/json" if env["CONTENT_TYPE"] != "application/json" - begin - @request_validator.call(env) - # response = @app.call(env) - # @response_validator.validate(request, response) - rescue OpenapiFirst::NotFoundError - PlugApp::Middleware::NotFound.new.call(env) - rescue OpenapiFirst::RequestInvalidError => e - error_hsh = ::ErrorSerializer.format(e.message) - Rails.logger.error(error_hsh) if print_user_api_errors? - return [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_hsh]] - rescue StandardError => e - raise e unless Rails.env.production? + validated_request = SPEC.validate_request(request) - logger.error( - "openapi.request_validation.error", - path: request.path, - method: request.env["REQUEST_METHOD"], - error_message: e.message, - ) + return @app.call(env) if validated_request.valid? + + case validated_request.error + when OpenapiFirst::Schema::ValidationError + error_arr = format_arr(validated_request.error.errors.map(&:error)) + Rails.logger.error(error_arr) if print_user_api_errors? + [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_arr]] + else + case validated_request.error.error_type + when :not_found + [PlugApp::HTTP::NOT_FOUND_I, { "Content-Type" => "application/json" }, [format_str("Not Found")]] + else + error_message = if validated_request.error.errors.present? + format_arr(validated_request.error.errors.map(&:error)) + else + format_str(validated_request.error.message) + end + + Rails.logger.error(error_message) if print_user_api_errors? + [PlugApp::HTTP::BAD_REQUEST_I, { "Content-Type" => "application/json" }, [error_message]] + end end + rescue StandardError => e + raise e unless Rails.env.production? + + logger.error( + "openapi.request_validation.error", + path: request.path, + method: request.env["REQUEST_METHOD"], + error_message: e.message, + ) end + end - @app.call(env) + private def format_str(error) + { + errors: [ + { + message: error, + }, + ], + }.to_json + end + + private def format_arr(errors) + { + errors: errors.each_with_object([]) do |error, arr| + arr << { + message: error, + } + end, + }.to_json end end end end