ソースを参照

Extract upload logic from mutations

Andrew Swistak 6 年 前
コミット
e4f8bd2854

+ 3 - 12
app/graphql/mutations/upload_many_pokemon.rb

@@ -5,20 +5,11 @@ module Mutations
     argument :base64_encoded_pokemon_files, [GraphQL::STRING_TYPE], required: true
 
     field :pokemon, [Types::PokemonType], null: true
-    field :errors, [GraphQL::STRING_TYPE], null: false
+    field :error, Types::ErrorType, null: true
 
     def resolve(base64_encoded_pokemon_files:)
-      client = PKParse::Client.new
-      response = client.parse_base64(base64_encoded_pokemon_files)
-
-      ::Pokemon.transaction do
-        @pokemon = ::Pokemon.create!(response.pokemon.map(&:to_h))
-      end
-
-      {
-        pokemon: @pokemon,
-        errors: [],
-      }
+      service = CreatePokemonFromBase64Service.new
+      service.execute(base64_encoded_pokemon_files)
     end
   end
 end

+ 5 - 9
app/graphql/mutations/upload_pokemon.rb

@@ -5,19 +5,15 @@ module Mutations
     argument :base64_encoded_pokemon_file, GraphQL::STRING_TYPE, required: true
 
     field :pokemon, Types::PokemonType, null: true
-    field :errors, [GraphQL::STRING_TYPE], null: false
+    field :error, Types::ErrorType, null: true
 
     def resolve(base64_encoded_pokemon_file:)
-      client = PKParse::Client.new
-      response = client.parse_base64(base64_encoded_pokemon_file)
-
-      ::Pokemon.transaction do
-        @pokemon = ::Pokemon.create!(response.pokemon.map(&:to_h))
-      end
+      service = CreatePokemonFromBase64Service.new
+      result = service.execute(base64_encoded_pokemon_file)
 
       {
-        pokemon: @pokemon.first,
-        errors: [],
+        pokemon: result[:pokemon]&.first,
+        error: result[:error],
       }
     end
   end

+ 8 - 0
app/graphql/types/error_type.rb

@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module Types
+  class ErrorType < Types::BaseObject
+    field :message, GraphQL::STRING_TYPE, null: false
+    field :type, GraphQL::STRING_TYPE, null: true
+  end
+end

+ 17 - 0
app/services/base_service.rb

@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class BaseService
+  private
+
+    def error(err)
+      {
+        error: err,
+        status: :error,
+      }
+    end
+
+    def success(pass_back = {})
+      pass_back[:status] = :success
+      pass_back
+    end
+end

+ 28 - 0
app/services/create_pokemon_from_base64_service.rb

@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class CreatePokemonFromBase64Service < BaseService
+  def execute(base64_encoded_pokemon)
+    response = client.parse_base64(base64_encoded_pokemon)
+
+    pokemon = ::Pokemon.transaction do
+      ::Pokemon.create!(response.pokemon.map(&:to_h))
+    end
+
+    success(pokemon)
+  rescue PKParse::Error => e
+    error(APIError::BaseError.new(e.message, internal_error: e))
+  rescue ActiveRecord::ActiveRecordError => e
+    PKParse.logger.error("Failed to commit parsed results: #{e}\n#{e.backtrace.join("\n")}")
+    error(APIError::BaseError.new('Failed to commit the uploaded pokemon.', internal_error: e))
+  end
+
+  private
+
+    def success(pokemon)
+      super().merge(pokemon: pokemon)
+    end
+
+    def client
+      @client ||= PKParse::Client.new
+    end
+end

+ 1 - 0
config/application.rb

@@ -17,5 +17,6 @@ module PokemonTrade
     # Application configuration can go into files in config/initializers
     # -- all .rb files in that directory are automatically loaded after loading
     # the framework and any gems in your application.
+    config.autoload_paths.push("#{config.root}/app/services")
   end
 end

+ 2 - 5
lib/pkparse/response_error.rb

@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-require 'English'
-
 module PKParse
   class ResponseError < Error
     def initialize(error)
@@ -15,9 +13,8 @@ module PKParse
         body = original_exception.http_body
         parsed_body = JSON.parse(body, symbolize_keys: true)
         @message = parsed_body[:error]
-      rescue StandardError
-        err = $ERROR_INFO
-        PKParse.logger.error("Exception parsing ResponseError http body:\n#{err}\n#{err.backtrace.join("\n")}")
+      rescue StandardError => e
+        PKParse.logger.error("Exception parsing ResponseError http body:\n#{e}\n#{e.backtrace.join("\n")}")
       end
   end
 end