2012-03-09 16 views
1

私はサーバーからXMLを引き出すAndroidアプリケーションを持っています。 XML.parse(...)が実行されたときJava AssertionError(java.lang.SocketException)の処理方法は?

public class FeedParser { 

    private final URL mURL; 

    public FeedParser(String feedUrl) { 
     try { 
      mURL = new URL(feedUrl); 
     } catch (MalformedURLException e) { 
      throw new RuntimeException(); 
     } 
    } 

    private InputStream getInputStream() throws IOException { 
     return mURL.openConnection().getInputStream(); 
    } 

    public FeedItem parseFeed() { 
     // SAX stuff here 

     try { 
      Xml.parse(getInputStream(), Xml.Encoding.UTF_8, 
        root.getContentHandler()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return result; 
    } 
} 

は時々、私は例外を取得:

AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground() 
AndroidRuntime: at android.os.AsyncTask$3.done(AsyncTask.java:200) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
AndroidRuntime: at java.lang.Thread.run(Thread.java:1019) 
AndroidRuntime: Caused by: java.lang.AssertionError: java.net.SocketException: Connection reset by peer 
AndroidRuntime: at android.util.Xml.parse(Xml.java:89) 
AndroidRuntime: at com.packagename.FeedParser.parseFeed(FeedParser.java:60) 
AndroidRuntime: at com.packagename.UpdateService$FeedLookupTask.doInBackground(UpdateService.java:84) 
AndroidRuntime: at com.packagename.UpdateService$FeedLookupTask.doInBackground(UpdateService.java:1) 
AndroidRuntime: at android.os.AsyncTask$2.call(AsyncTask.java:185) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
AndroidRuntime: ... 4 more 
AndroidRuntime: Caused by: java.net.SocketException: Connection reset by peer 
AndroidRuntime: at org.apache.harmony.luni.platform.OSNetworkSystem.read(Native Method) 
AndroidRuntime: at dalvik.system.BlockGuard$WrappedNetworkSystem.read(BlockGuard.java:273) 
AndroidRuntime: at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:458) 
AndroidRuntime: at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:85) 
AndroidRuntime: at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:65) 
AndroidRuntime: at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:140) 
AndroidRuntime: at java.io.BufferedInputStream.read(BufferedInputStream.java:225) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.readLine(HttpURLConnectionImpl.java:660) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream.readChunkSize(ChunkedInputStream.java:77) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream.read(ChunkedInputStream.java:45) 
AndroidRuntime: at java.io.InputStream.read(InputStream.java:157) 
AndroidRuntime: at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:516) 
AndroidRuntime: at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:479) 
AndroidRuntime: at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:318) 
AndroidRuntime: at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:275) 

私は、このようなエラーを処理する方法は?

EDITキャッチエラーはプログラミングスタイルが悪いことを知っているので、私はより洗練された解決策を模索しています。

+1

は、構文解析/フェッチを再試行してください:それは心の中で持っているもう一つの選択肢であるので、原因を持つAssertionErrorが(別のThrowableから構成されている)ことを非常に奇妙なのですか?基本的に例外は悪くないです、それは何かが間違っていることを示しています。だから、それをやり直す方法を考えてみてください(永遠に再試行しないでください!それを制限する再試行カウンタを作ってください)... – WarrenFaith

+0

エラーを捕まえるのは悪い考えです。これを行うには、キャッチ(Throwable)を書く必要がありますか? –

+0

いいえ、そうではありません。 catch(AssertionError e)で十分です。 –

答えて

1

ピアによる接続リセットは、読んでいるリモートサーバーが接続を閉じていることを意味します。リモート側がこれを行うのは必ずしもネットワークエラーではありません。それはいくつかの理由で可能です。サーバーのプロトコルを知らなくても、正確な理由を知ることは難しいです。

上記のように、制限付きの回数だけキャッチして再試行するようにコードを設定することができます。エラーをキャッチするのは悪い考えではありません。

xmlのサイズによっては、文字列バッファに読み込んで解析することもできます。大量のデータを使用すると、サーバー接続がパース時よりもはるかに短くなるため、リセットの可能性が低くなります。私はあなたが解析している間にTCPウィンドウが長い間閉じられていて、結局相手が死んだと判断して接続をリセットするシナリオを考えています。

+1

@JarleHansenなぜエラーをキャッチするのは悪い考えですか?それが例外であれば、それを捕まえないで、x回再試行し、それでも失敗したら再投げてください。 – ebaxt

+0

@JarleHansenもちろん、リモートがクライアントでハングアップするのは「重大な問題」ですが、おそらくサーバーがちょうど忙しかったでしょうか?この場合、エラーをキャッチして賢明な回数をやり直すことは、素晴らしい考えです。 – alphazero

+0

あなたは正しいです、これは実際にAssertionErrorをキャッチする必要がある場合のようです。この問題に私の間違い。 –

0

AssertionErrorは、のアサーションには、が間違っていることを警告する標準的な方法を提供します。

よく使うと、「ここにコーディングのバグがあります」と言われています。なぜなら、AssertionErrorが(拡張)Errorであり、 Exception:(実行時に)回復不能であることを通知します(アルゴリズムを再コード化する必要があるため)。

このエラーのその他の用途は、契約に違反しているため間違っています。だから、あなたの質問に答える、あなたは方法の中でそれを処理することができます

  • エラーを投げるコードがあなたであれば(私はこれがあなたの質問与えられたケースである疑いが、将来的にする必要があります):アルゴリズムを見直して修正します。
  • それは、サードパーティのライブラリからの場合:その作者にバグを登録する(あるいはあなた自身でそれを解決しようとする)

しかし、あなたはあなたのコードでそれを扱うべきではありません。

追加の注意:あなたのケースでは、android.util.Xml.parse()が正しく使用しているかどうか疑問に思っています。多分、このライブラリがうまく実装されていません...