最初にいくつかのチェックを行うレーキタスクがあります。チェックの1つが失敗した場合、レーキタスクから早期に戻りたい場合、残りのコードは実行しません。
解決策は、コードから戻りたい場所に戻りを配置することだと思いましたが、次のエラーが表示されます
unexpected return
Rakeタスクは基本的にブロックです。ラムダを除くブロックはreturnをサポートしていませんが、rakeタスクではメソッドでreturnを使用するのと同じ効果があるnext
を使用して次のステートメントにスキップできます。
task :foo do
puts "printed"
next
puts "never printed"
end
または、メソッド内のコードを移動し、メソッド内でreturnを使用できます。
task :foo do
do_something
end
def do_something
puts "startd"
return
puts "end"
end
私は2番目の選択を好みます。
タスク内からabort(message)
を使用して、メッセージでそのタスクを中止できます。
私はabort
を使用する傾向がありますが、これはそのような状況ではより良い代替手段です。例えば:
task :foo do
something = false
abort 'Failed to proceed' unless something
end
multipleブロックレベルから抜け出す必要がある場合は、 fail を使用できます。
例えば
task :something do
[1,2,3].each do |i|
...
fail "some error" if ...
end
end
( https://stackoverflow.com/a/3753955/1154 を参照してください。)
「rake aborted!」を発生させずにrakeタスクを終了するつもりだった場合メッセージを印刷する場合は、「中止」または「終了」のいずれかを使用できます。しかし、「abort」をレスキューブロックで使用すると、タスクが終了し、エラー全体が出力されます(--traceを使用しなくても)。だから「出口」は私が使用するものです。
withエラー(つまり、1
の終了コード)を返す場合は、abort
を使用します。 =は、終了時に出力されるオプションの文字列パラメーターも受け取ります。
task :check do
errors = get_errors
abort( "There are #{errors.count} errors!" ) if errors.any?
# Do remaining checks...
end
コマンドライン:
$ rake check && echo "All good"
#=> There are 2 errors!
エラーを返さずにを返す場合(つまり、0
の終了コード)exit
を使用します。 =、これはは行いません文字列パラメーターを取ります。
task :check do
errors = get_errors
exit if errors.empty?
# Process errors...
end
コマンドライン:
$ rake check && echo "All good"
#=> All good
これは、cronジョブで使用する場合、またはrakeタスクが成功したかどうかに基づいて後で何かを行う必要がある場合に重要です。
レーキタスクをテストするとき、実際にはnext
の単なるラッパーであるabort
は望ましい動作ではないため、Simone Carlettiが提案するexit
アプローチを使用しました。
例:
task auto_invoice: :environment do
if Application.feature_disabled?(:auto_invoice)
$stderr.puts 'Feature is disabled, aborting.'
next
end