37

データベースの問題が原因で例外が発生したかどうかを確認する必要があります。例外を受け取り、その原因に「ORA」文字列が含まれているかどうかを確認し、それを返します (「ORA-00001」など)。ここでの問題は、受け取った例外が他の例外の中にネストされていることです。そのため、それがオラクルの例外であるかどうかがわからない場合は、その例外の原因などを調べる必要があります。これを行うためのよりクリーンな方法はありますか?特定の例外の最初の原因 (深くネストされた例外) を知る方法はありますか?

私の現在のコードは次のようになります。

private String getErrorOracle(Throwable e){
        final String ORACLE = "ORA";
        if (e.getCause() != null && e.getCause().toString().contains(ORACLE)){
            return e.getCause().toString();
        } else if(e.getCause() != null){
            return getErrorOracle(e.getCause());
        } else {
            return null;
        }
    }
4

13 に答える 13

87

車輪の再発明を避けるために、Apache Commons Langを使用している場合は、 ExceptionUtils.getRootCause()を見てください。

そのためだけにライブラリを含める価値はありますか? そうでないかもしれない。しかし、すでにクラスパスにある場合は、そこにあり、「単純な」実装では実行できないいくつかのことを実行することに注意してください (たとえば、原因チェーンのサイクルを処理する... うーん!)

于 2009-11-25T00:20:25.970 に答える
18

すでにGuavaを使用している場合は、Throwables.getRootCause()が助けになります。

于 2013-05-11T15:10:13.273 に答える
15

原因のない例外が発生するまで例外チェーンをトラバースし、最後のメッセージが必要な場合はそのメッセージを返します。

関数が最初の原因を取得するのは、それが存在する場合のみです。

パッケージ内の最初の原因を見つけることを検討することをお勧めします。実際の最も深い原因はオラクルの例外である可能性があり、これは役に立ちますが、問題の発生場所がわからない限り、修正するのに苦労します。

于 2009-11-24T17:31:57.137 に答える
4

おそらくあなたの使い方には少しやり過ぎですが、私はそれがきれいだと思います(そして再利用可能です)

interface ThrowablePredicate {
    boolean accept(Throwable t);
}

public OracleErrorThrowablePredicate implements ThrowablePredicate {
    private static final ORA_ERR = "ORA";

    public boolean accept(Throwable t) {
        return t.toString().contains(ORA_ERR);
    }
}


public class CauseFinder {

   private ThrowablePredicate predicate;

   public CauseFinder(ThrowablePredicate predicate) {
      this.predicate = predicate;
   }

   Throwable findCause(Throwable t) {
      Throwable cause = t.getCause();

      return cause == null ? null 
         : predicate.accept(cause) ? cause : findCause(cause)
   }
}


// Your method
private String getErrorOracle(Throwable e){
    return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
}
于 2009-11-24T17:45:43.987 に答える
2

オラクルによってスローされたエラーはすべて SQLException にラップされると思います(間違っている場合は誰かが私を修正してください)。SQLException にアクセスしたら、呼び出すことができるはずです

getErrorCode() この SQLException オブジェクトのベンダー固有の例外コードを取得します。

私は試したことがないので、これが機能するかどうか教えてください:-)

カール

于 2009-11-24T17:37:35.830 に答える
2

SQLExceptionのコードチェックを改善できます

import java.sql.SQLException;

private static final String ORACLE = "ORA";

public String doHandle(Throwable t) {
    if (t.getClass().isAssignableFrom(SQLException.class)) {
    SQLException e = (SQLException) t;
    int errCode = e.getErrorCode();
    String state = e.getSQLState();
    String msg = e.getMessage();
    if (msg.contains(ORACLE)) {
        return msg;
        }
    } else {
        if (t.getCause() != null) {
            return this.doHandle(t.getCause());
            }
        }
    return "";
}

また、Oracleの「errCode」には、ORA-nnnnに関連付けられた番号が含まれていると思います

于 2009-11-24T17:45:09.307 に答える
0

ThrowableクラスのgetStackTrace()を使用できます。これにより、StackTraceElementsのスタックを操作できるようになります。StackTraceElements []を反復処理して、「ORA」文字列を見つけることができます。

例が必要な場合はお知らせください。

于 2009-11-24T17:33:01.690 に答える
-1

スローされる例外が常に OracleException などの特定のタイプになる場合は、その例外だけをキャッチできます。

例えば:

try {

    ...

} catch(OracleException oe) {

    ...

}

これは、特定の Oracle 例外がスローされる場合にのみ適用されます。私は Oracle についてあまり知らないので、これを試す前に、それが起こっているかどうかを調べたいと思うでしょう。

于 2009-11-24T17:40:30.567 に答える
-2

2015 年 1月 28日、上記の解決策のいずれでも問題を解決できなかったため、以下を使用することをお勧めします。

e.getMessage().toString();

Ps: Android で使用しています。

于 2016-01-28T07:10:06.977 に答える