try catchステートメントのコメント
-
03-07-2019 - |
質問
try-catchステートメントでエラー処理を説明する適切な場所は何ですか? tryブロックまたはcatchブロックの先頭に説明的なコメントを入れることができるようです。
// Possible comment location 1
try
{
// real code
}
// Possible comment location 2
catch
{
// Possible comment location 3
// Error handling code
}
解決
通常は次のことを行います。処理される例外が1つだけの場合、自己文書化する必要があるため、通常は気にしません。
try
{
real code // throws SomeException
real code // throws SomeOtherException
}
catch(SomeException se)
{
// explain your error handling choice if it's not obvious
}
catch(SomeOtherException soe)
{
// explain your error handling choice if it's not obvious
}
他のヒント
"コメントは嘘です。これらの変数名と一般的なロジックを操作して、回避できるようにします。本当にうそをつく必要がある場合は、catchブロック内で実行してください。
それは重要ではないと思います。
コメントの際に覚えておくべき重要なことは、コードが何をしているのか何ではなく理由に対処することだと思います。これは、複雑なロジックを簡潔なコメントで説明すべきではないということではありませんが、その理由は非常に重要です。
追加のコメントを必要としないようにコードを設定するだけではどうですか?
try
{
performDifficultAct( parameter );
}
catch (ArgumentOutOfRangeException couldNotFindArgument)
{
// handle exception
}
catch (Exception otherUnknownException )
{
// handle exception
}
何が起こっているかを示すために変数とメソッドの命名を使用できる場合、文書化する必要はありません。例外を記録または発生させる必要がある場合、文書化する必要はありません。ソースコードのログメッセージは、とにかく説明が必要です。コードに追加のドキュメントが必要なのは、コードが何をしているのかが完全に非自明である場合、または追加する必要がある簡単なミスや曖昧なステップがある場合のみです。将来のコード。
編集:少し明確にするために、これらの" catch"の使用方法をもう少し説明します。メンテナンスプログラマと、ソフトウェアを使用するユーザー/サポート/ QA /他の人の両方に役立つ情報を提供するステートメント。また、コードに追加のコメントを絶対に追加したい状況の例:
public void PerformSomeActionOrOther(string parameter)
{
try
{
// For some reason an eleven character string causes a bluescreen from Kernel32
if (parameter.Length==11) parameter+=" ";
performDifficultAct( parameter );
}
catch (ArgumentOutOfRangeException couldNotFindArgument)
{
this.Log.WriteLn("Argument out of range exception in ArbitraryClass.PerformSomeActionOrOther");
this.Log.WriteLn(String.Format("Probable cause is that {0} is not in the array", parameter));
this.Log.WriteLn(String.Format("Exception: {0}", couldNotFindArgument.Message));
}
catch (Exception otherUnknownException )
{
this.Log.WriteLn("Unexpected exception in ArbitraryClass.PerformSomeActionOrOther");
this.Log.WriteLn(String.Format("Exception: {0}", otherUnknownException.Message));
throw( otherUnknownException );
}
}
「例外処理ブロックをここから開始する」以外は何と言ったらいいのでしょうか? catchステートメントに対するコメントの方が優れていますが、一般的に言って、もう一度言いますか? " NullPointerExceptionを処理する"?
アプリケーションドメインの例外へのチェーンなど、エキサイティングなことをしていると言う必要があるコメントIFFを探します。
よく書かれたtry / catchは簡潔かつ具体的である必要があると思います。 @Jasonには同意します。なぜがより重要ですが、同様に、catch内のコードをできるだけ簡潔にすることが重要です。
特定の例外を使用してキャッチした場合にも役立ちます。たとえばJavaを使用している場合は、汎用の例外ではなくNullPointerExceptionをキャッチしてください。これは、try catchが存在する理由と、それを解決するために何をしているのかを説明する必要があります。
一貫性があれば、場所は関係ありません。私の個人的な好みは次のとおりです。
//comment 1: code does XYZ, can cause exceptions A, B, C
try {
//do something
}
//comment 2: exception A occurs when foo != bar
catch (ExceptionA a) {
//do something
}
//comment 3: exception B occurs when bar is null
catch (ExceptionB b) {
//do something
}
//comment 4: exception B occurs when foo is null
catch (ExceptionC c) {
//do something
}
これはあなたが探している答えではないことは知っていますが、まったくコメントしないでください。コードがコメントなしで単独で立つほど明確でない場合は、それができるまでリファクタリングする必要があります。 Jeffrey Palerm oはブログの投稿で最高の状態を示しています。
通常、コメントは次のいずれかを文書化する傾向があります。
- コンパクトすぎるコード。次のようなもの:
++ i?-g:h-i;
- 要約する必要がある長いコードブロック
- 使い捨てのコード、または既存の明確な理由のないコード
例外ブロックに対する簡単なコメントの簡単な例、およびコメントの必要性を排除するバージョンについては、以下を参照してください。
bool retries = 0;
while (retries < MAX_RETRIES)
{
try
{
... database access code
break;
}
// If under max retries, log and increment, otherwise rethrow
catch (SqlException e)
{
logger.LogWarning(e);
if (++retries >= MAX_RETRIES)
{
throw new MaxRetriesException(MAX_RETRIES, e);
}
}
// Can't retry. Log error and rethrow.
catch (ApplicationException e)
{
logger.LogError(e);
throw;
}
}
上記のコメントは再利用性を促進しますが、基本的にコードとコメントの両方を維持する必要があります。これをリファクタリングしてコメントなしでより明確にすることは可能です(そして望ましいです)。
bool retries = 0;
while (canRetry(retries))
{
try
{
... database access code
break;
}
catch (SqlException e)
{
logger.LogWarning(e);
retries = incrementRetriesOrThrowIfMaxReached(retries, e);
}
catch (ApplicationException e)
{
logger.LogError(e);
throw;
}
}
...
private void incrementRetriesOrThrowIfMaxReached(int retries, Exception e)
{
if (++retries >= MAX_RETRIES)
throw new MaxRetriesException(MAX_RETRIES, e);
return retries;
}
private bool canRetry(int retries)
{
return retries < MAX_RETRIES;
}
後者の例は、非常に微妙な利点のためにより多くのコードのように見えるかもしれませんが、利益を誇張することはできません。コードも同じように理解できますが、コードを説明するためにメタデータ(コメント)のセットを別に用意する必要がないという利点があります。コードはそれ自体を説明します。 catchコードブロックが長すぎて要約するコメントが必要な場合は、読みやすくするために別のメソッドにリファクタリングすることを検討してください。