11

私は Java を初めて使用し、エラー スタック トレースがスローされ、その後 Web アプリケーションのエンド ユーザーに表示されるときに使用される書式設定規則に精通していません。

Oracle データベースでの私の経験では、エラー スタックには、スキーマやプロシージャ名、行番号などの内部情報が含まれています。これは、デバッグには役立ちますが、ユーザーには見えないようにしたいと考えています。次に例を示します。

java.sql.SQLException : ORA-20011: Error description here
ORA-07894: at "NAME_OF_SCHEMA.PROCEDURE_NAME", line 121
ORA-08932: at line 10

ユーザーに表示したい文字列はError description here. 正規表現を使用してこの文字列を抽出できます。これは、(1) この文字列は常に最初の行にあるため、エラー スタック トレースの最初の行を抽出できること、(2) この文字列は常に末尾で始まりError末尾で終わることがわかっているためです。行の。[Oracle ユーザーへの注意 (誤解を招きたくない): 上記は、RAISE_APPLICATION_ERROR を で始まるエラー文字列で使用した場合にのみ適用されます。Errorそれ以外の場合、テキストErrorは表示されません]。

Java に関する私の質問は次のとおりです。

(1) エラー スタックでユーザーに見せたくない機密性の高いものはありますか? もしそうなら、何?たとえば、ファイル パス、サーバー名/IP などです。

(2) 非機密情報を抽出するために信頼できる Java エラー スタック トレースのフォーマット規則はありますか? または、他の人はこの懸念にどのように対処しますか?

更新 1:

これまでのすべての返信に感謝します。非常に役に立ちました。多くの人が、エラーを有用なユーザー メッセージにマップするなどの機能を使用するようにコメントしていますがgetUserFriendlyMessage()、誰かがこのマッピングを拡張できるのではないかと思います。つまり、一般的なエラー (SQL、I/O など) の場合、このエラー スタックを検索して発生したエラーの種類を特定するために使用できる "信頼できる" 識別子と、対応するどのテキスト文字列をお勧めしますか?このエラー メッセージにマップしてユーザーに表示するには? 以下の@Adarshrの応答は良いスタートです。例えば、

Identified Expected   If found in error stack, display this friendly msg to user
-------------------   ----------------------------------------------------------
SQLException          An error occurred accessing the database. Please contact support at support@companyname.com.
IOException           Connection error(?). Please check your internet connection.

コンパイル関連のエラーに対処する必要はないと仮定しますが、通常の使用中にエンド ユーザーが経験する可能性のあるエラーに焦点を当てます。参考までに、ランタイム エラー メッセージのリストを以下に示します: http://mindprod.com/jgloss/runerrormessages.html#IOEXCEPTION

または、スタック トレースの FIRST LINE を使用してユーザーに表示することはできますか? このリンクは、上記の最初の質問で私が得ていたもののようなものです:

http://www3.ntu.edu.sg/home/ehchua/programming/howto/ErrorMessages.html

たとえば、識別子Exceptionが常に使用されている場合Exception、最初の行と最後の行の間にあるテキストを単純に抽出できます。いつもそこにいると頼れるかどうかはわかりませんException

4

7 に答える 7

7

ユーザーにそのゴブルディグックを表示するべきではありません。ほとんどの人にとっては意味がなく、役に立ちません。ご想像のとおり、悪意のあるユーザーが使用できる可能性のある脆弱性を示唆する実装の内部も公開されます。

代わりに、例外をキャッチしてログに記録し、よりわかりやすいエラー メッセージをユーザーに表示する必要があります。getMessage()例外のメッセージ部分を抽出するために使用できます。例外にメッセージがない場合は、「利用可能な詳細はありません」のようなものを表示します。

アップデート:

質問の更新に基づいていくつかのコメントがあります。まず、ユーザーに優しく、セキュリティを確保するために、システムの内部からユーザーを完全に隔離します。(たとえば、java.sql パッケージを使用していることを知っていても、巧妙なハッカーに脆弱性を示唆する可能性があります。) したがって、ユーザーに何かを表示するときに、例外メッセージ、スタック トレースの最初の行、またはそのようなものを使用しないでください。 .

次に、すべてのエラーを例外レベル (コード内でエラーが発生するレベル) から、ユーザーにとって適切な抽象化レベルにあるメッセージにマッピングする必要があります。これを行う適切な方法は、システムの内部構造と、例外が発生したときにユーザーが何をしようとしていたかによって異なります。これは、例外をキャッチする各レイヤーがそれを抽象化の上位レイヤーで例外に変換するように、システムをレイヤーに構造化することを意味する場合があります。Java 例外は、別の例外 (原因) をラップできます。例えば:

public boolean copyFile(File source, File destination) throws CopyException {
    try {
        // lots of code
        return true;
    } catch (IOException e) {
        throw new CopyException("File copy failed", e);
    }
}

次に、これを User クラスの上位レベルで使用できます。

public boolean shareFile(File source, User otherUser) throws ShareException {
    if (otherUser.hasBlocked(this) {
        throw new ShareException("You cannot share with that user.");
    }
    try {
        return copyFile(source, otherUser.getSharedFileDestination(source));
    } catch (CopyException e) {
        throw new ShareException("Sharing failed due to an internal error", e);
    }
}

(上記のコードが、システムで使用すべきコードの提案としてではなく、例外をより高いレベルの抽象化に変換するという考えを説明することを意図していることは明らかです。)

このような処理を (何らかの方法でメッセージやスタック トレースを処理するのではなく) 行う理由は、例外 (たとえば、「許可が拒否されました」というメッセージを伴う IOException) がユーザーにとって (およびお使いのシステム) さまざまなコンテキストで。

于 2012-06-08T18:29:36.487 に答える
5

例外メッセージ/スタック トレースをエンド ユーザーに直接表示しないでください。代わりに、例外 - メッセージ マッピング アプローチを使用してみてください。

例えば:

  • SQLException- データベース エラーが発生しました。後でもう一度やり直してください
  • RuntimeException/ Exception- エラーが発生しました。後でもう一度やり直してください

実際、可能な限り一般的なものにすることができます。おそらく、カスタム エラー コード マッピングを使用できます。たとえば、E0001for SQLExceptionE0000forExceptionなどをエンド ユーザーに表示します。これは、最終的にカスタマー サービスにエラー コードを連絡する際に役立ちます。

于 2012-06-08T18:31:47.063 に答える
3

エンド ユーザーが理解できない情報 (すべてのスタック トレース全体を含む) を表示しないでください。このような例外をキャッチしたときに表示されるエラーは、エンドユーザーの言語で次のように表示されます。

  • プログラムに一時的な問題が発生しました。サポートが必要な場合は、テクニカル サポート ラインにお電話ください。

エンド ユーザーは、プログラムの内部組織、データベース、スタックなどを気にする必要はありません。彼らが知っているのは、うまくいくはずだと思っていたことが失敗したということだけです。そのため、彼らは支援を求めています。

スタック トレースはエラー ログ用です。自分用に保存したり、テクニカル サポートに電子メールで送信したりできますが、エンド ユーザーには表示したくありません。

于 2012-06-08T18:31:50.107 に答える
1

アプリがデバッグ モードの場合にのみ、スタック トレースを表示する必要があります。本番モードでは、一般的なエラー メッセージを表示 (または実装Exception.getUserFriendlyMessage()) し、エラーをログに記録する (可能であればログ ID を提供する) 必要があります。

于 2012-06-08T18:30:58.453 に答える
1

ユーザーに表示したい文字列はError description here.

Exception.getMessage()この目的で使用できますが、Juan Mendez が提案したように、エンド ユーザーにエラーを表示するためのより「ユーザー フレンドリな」エラー メッセージ メカニズムを実装することを検討してください。

スタック トレース内のクラス、メソッド、フィールドの名前をエンド ユーザーに見せたくない場合は、 Proguard などの難読化ツールの使用を検討してください。難読化されたスタック トレースをログ ファイルに出力し、ReTrace を使用して難読化を解除してデバッグするのが好きです。

(1) エラー スタックでユーザーに見せたくない機密性の高いものはありますか? もしそうなら、何?たとえば、ファイル パス、サーバー名/IP などです。

スローされる例外に依存する可能性があると思います。例外をログに記録するかどうかを選択することは、アプリケーションのセキュリティと問題を効果的に診断できるかどうかとのトレードオフです。私はケースバイケースで考え、必要に応じてコメントを残して、ログに記録するか記録しないかの理由を説明します。

于 2012-06-08T18:31:08.700 に答える
1

他の人が言ったように、スタックトレースをユーザーに報告するべきではありません。他の何人かは、テキストを表示することを提案していgetMessage()ます。そうしないことをお勧めします。私が前に言ったように:

  • 例外がスローされたときにメッセージが作成されました。したがって、ユーザーへの報告には不適切な、非常に低レベルの情報しか提供できません。
  • throw哲学的には、メッセージを使用することは、エラー処理の検出と開始 (部分) を処理と報告 (部分) の完了から分離するという、例外の要点全体に反しているように思えますcatch。メッセージを使用するということは、メッセージがレポートに適している必要があることを意味します。これにより、レポートの責任が、検出と開始のみを担当する場所に移されます。つまりgetMessage()、 の設計の一部がThrowable間違っていたと言えます。
  • メッセージはローカライズされていません。その名前にもかかわらず、getLocalizedMessage()使用したいロケールがcatch例外 (英語のシステム管理者によって読み取られるシステム ログにレポートが移動するか、ウィンドウにポップアップ表示されるか) が発生するまでわからない可能性があるため、あまり役に立ちません。 GUI のフランス人ユーザー?)。
于 2012-06-12T13:17:45.353 に答える
1

ユーザー名とパスワードは、ユーザーに見せたくない機密情報であることは明らかです。また、あなたが言ったように、ファイル システム パス、サーバー名、および IP アドレスも非表示にする必要があります。

このException.getMessage()メソッドは、スタック トレース全体ではなく、スローされた例外のメッセージのみを返します。しかし、あなたが与えた例では、2行目と3行目も例外メッセージの一部であるように見えるので、それは役に立ちません。

しかし、ユーザーにスタック トレースを表示するのは良い習慣ではありません機密情報を含めることができるだけでなく、ユーザーにとっては、クリンゴンと同じくらい読みやすいものです。代わりに、キャッチされていないすべての例外をログに記録し、よりユーザーフレンドリーなメッセージをユーザーに表示する必要があります。

于 2012-06-08T18:37:08.173 に答える