Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Railsでのデバッグ例外

Railsアプリケーションでエラーが発生した場合、例外とスタックトレースは、問題が発生した場所を見つけるのに役立ちます。どこで何が起こったのかを知った後、理由を見つける必要があります それは起こった。この記事では、バックトレースを使用してRailsアプリケーションのバグを見つける方法について説明します。

NoMethodError (undefined method `request_uri' for #<URI::Generic >):

app/models/product.rb:8:in `download_image!'
app/controllers/products_controller.rb:5:in `create'

この例の例外では、 NoMethodErrorを受け取りました #undefinedmethod `request_uri' そのメッセージとして。この例外は問題が何であるかをすぐには教えてくれないので、何が起こったのかを見つけるためにスタックトレースを調べる必要があります。

app/models/product.rb:8:in `download_image!'
app/controllers/products_controller.rb:5:in `create'

スタックトレースを見ると、例外が download_image!から発生したことがわかります。 Productのメソッド モデル。コードで調査を続け、スタックトレースをたどって、何が問題になっているのかを調べます。

モデルを開くと、8行目(例外が発生した場所)が Net ::HTTP.get(uri)を呼び出していることがわかります。 、そのように見える uri 期待するオブジェクトではありません。

require 'net/http'
 
class Product < ApplicationRecord
  after_save :download_image!
 
  def download_image!
    uri = URI(image_url)
    contents = Net::HTTP.get(uri)
 
    File.open("public#{local_image_path}", 'wb') do |file|
      file.write contents
    end
  end
 
  def local_image_path
    "/product_#{id}.png"
  end
end

download_image!以降 メソッドはafter_save コールバック、新しい製品を保存した直後に実行されることがわかっています。

uri 変数は、 image_urlという名前のメソッドから作成されます 7行目。それがどこから来ているのかを知るために、スタックトレースをもう一度見て、 Product#createを確認します。 メソッドはProductsController#createから呼び出されます 。

class ProductsController < ApplicationController
  def create
    @product = Product.new(product_params)
 
    if @product.save
      redirect_to @product, notice: 'Product was successfully created.'
    else
      render :new
    end
  end
 
  private
    def product_params
      params.require(:product).permit(:title, :description, :image_url, :price)
    end
end

あはは! ProductsController#create product_paramsを使用して新しい製品を作成します 、これには:image_urlが含まれます 探していたパラメータ。

image_urlを知っています 属性は、壊れたURIを構築するために使用されます。 image_urlを離れる場合 新製品を作成するときにフィールドが空の場合、問題を正常に再現できます。

この場合、 URIを作成します 値として空の文字列を使用すると、 URI ::Genericになります。 URI ::HTTPの代わりにオブジェクト 、URLの形式を判別できないため。前者には#request_uriがないため メソッドの場合、 NoMethodErrorが発生します Net ::HTTP.getから 。

プロジェクトの要件によっては、フィールドが空でないことを確認するための検証を追加すると、問題が修正される可能性があります。画像のURLが空でないことを確認するだけでは、この実装で発生する可能性のあるすべての問題を修正することはできません(たとえば、渡された値がURLでない場合でも例外が発生します)が、良いスタートです。

スタックトレースを使用した例外の追跡

Railsのログは、問題をデバッグするための優れた方法を提供します。発生した例外は一見しただけでは必ずしも意味がありませんが、問題の原因が埋もれている場合でも、コードが問題に到達するために行った手順を慎重に撤回することは、通常、何が悪かったのかを見つけるための優れた方法です。アプリのもう少し深いところにあります。

この記事がどのように気に入ったか、質問がある場合、次に何を読みたいかをお知らせください。@AppSignalまでお知らせください。


  1. RailsをAWSLambdaにデプロイする

    サーバーレスコンピューティングは、サーバーの管理とプロビジョニングの作業をクラウドプロバイダーに任せるのに役立ち、ほとんどのテクノロジーチームにとって急速に重要になっています。 AWS Lambdaは、多くのテクノロジーチームで使用されているサーバーレステクノロジーの一種です。 AWS Lambdaは、NodeJS、Java、Python、Rubyなどのコアプログラミング言語のほとんどをサポートしています。コアプログラミング言語はサポートされていますが、これらの言語で構築されたフレームワークの一部である機能に依存してサーバーレス関数を実行したい場合があります。この投稿では、AWSLambdaで

  2. Rails5でのAngularの使用

    あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた