rakeのエラー表示がちょっとだけ便利になりました。

rake v13.1.0がリリースされました 🎉

https://rubygems.org/gems/rake/versions/13.1.0

このリリースには私が実装した改善が含まれているので紹介します。 というか書かないと環境変数とか誰にも気づかれなさそう。

Support `#detailed_message` when task failed by ksss · Pull Request #486 · ruby/rake · GitHub

rake task実行時に何らかのエラーによって失敗したとき、error_highlightやdid_you_meanが効くようになりました。

before

$ bundle exec rake demo
rake aborted!
NoMethodError: undefined method `opject_id' for main:Object

after

$ bundle exec rake demo
rake aborted!
NoMethodError: undefined method `opject_id' for main:Object (NoMethodError)

  p self.opject_id
        ^^^^^^^^^^
Did you mean?  object_id

これまでは発生したエラークラスの#messageメソッドを表示していたのですが、#detailed_messageというメソッドが呼べるならこっちを呼び出すようになります。

ruby v3.2.0からException#detailed_messageが導入されており、これを利用しています。

エラークラスに#detailed_messageメソッドさえあればv3.1以前のrubyでも動くっちゃ動くのですが、稀なケースだと思われます。

rbsはv.3.1でも#detailed_messageを呼べるようにしたのでこの施策は有効です。

Debug at stop when task fail by ksss · Pull Request #489 · ruby/rake · GitHub

環境変数RAKE_DEBUGに何かしらの値が入っていると、rake taskが失敗したときにdebug gemによるデバッガーが起動します。

$ RAKE_DEBUG=1 bundle exec rake demo
undefined local variable or method `aaa' for main:Object
[30, 36] in ~/src/github.com/ksss/rake/Rakefile
    30| end
    31|
    32| task default: :test
    33|
    34| task :demo do
=>  35|   aaa
    36| end
=>#0 block in <top (required)> at ~/src/github.com/ksss/rake/Rakefile:35
  #1    [C] Kernel.load at ~/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/cli/exec.rb:58
  # and 14 frames (use `bt' command for all frames)
(rdbg:postmortem)

これまでrdbgコマンドでrakeタスクに対してブレイクポイントを仕込む事はできましたが、エラー発生時にデバッガーを起動するpostmortem機能を使っても最後に起きたexceptionに対してデバッガーが起動するので、本来調べたかったコンテキストが失われた状態になっていました。

そこで rspec-debug gemをヒントにRake::Task#execute実行中に発生したエラーに対してpostmortemを起動することで、本来得たかったコンテキストを得ることができるようになりました。

もちろんdebug gemが使える状況でなければ環境変数をつけても起動しないのでご注意ください。

なにか問題があれば直すので教えて下さい。

まとめ

rake便利。