2012-06-01 6 views
10

新しいJVMに、スカラ座での作業と2.0ベストプラクティス:のjava.net.URLでキャッチ障害ポイント

を再生する私は、プレイするAuthorize.netを経由して決済処理を必要とするものをレガシーアプリケーションを超える変換しています。 java.net.URLソースを見てみると、潜在的な障害の可能性が数多くあります。私が下に書いたインターフェースを与えられれば、どこにtry/catchブロックを実装しますか?私はおそらく、クライアントコードに

import java.net.{URL, URLEncoder} 
import java.io.{BufferedReader, DataOutputStream, InputStreamReader} 
import javax.net.ssl._ 

trait Authnet { 
    private val prodUrl = "https://secure.authorize.net/gateway/transact.dll" 
    private val testUrl = "https://test.authorize.net/gateway/transact.dll" 

    protected def authNetProcess(params: Map[String,String]) = { 
    val(conn, urlParams) = connect(params) 
    val request = new DataOutputStream(conn.getOutputStream) 
    request.write(urlParams.getBytes) 
    request.flush() 
    request.close() 
    val response = new BufferedReader(new InputStreamReader(conn.getInputStream)) 
    val results = response.readLine().split("\\|") 
    response.close() 
    results.toList 
    } 

    private def connect(params: Map[String,String]) = { 
    val urlParams = (config ++ params) map { case(k,v) => 
     URLEncoder.encode(k, "UTF-8") + "=" + URLEncoder.encode(v, "UTF-8") 
    } mkString("&") 

    lazy val url = if (isDev) new URL(testUrl) else new URL(prodUrl) 
    val conn = url.openConnection 
    conn.setDoOutput(true) 
    conn.setUseCaches(false) 
    (conn, urlParams) 
    } 

    private val config = Map(
    'x_login  -> "...", 
    'x_tran_key  -> "...", 
    ... 
) 
} 

答えて

0

EDIT
まあ、接続/ストリーム・プロセスの一部が失敗した場合、トランザクションを呼び出しするか、[エラー、成功]を返す、それに応じてメソッドのシグネチャを適応させる必要があります接続されているので、接続の開始時にエラーをキャプチャするだけで愚かです。私はちょうどcatching (operation) optionブロックのトランザクション全体をラップして、それを残しています。私はあまり心配していません:エラーの正確な原因(何がログに記録されても)は一時的なので、それをキャッチして、ユーザーに再試行させてください。エラーが続く場合は、ご連絡...

ORIGINAL OK、まあ、最高得票と最新コメントの欠如を考えると、私は描くことができる唯一の結論はで...ここの周りの誰もが、彼らは」何を知っていますやって! heh、heh、joking ;-)

私はJVMを初めて使っていますが、try/catch/finally bloatは古くなっています。私は今、私は(私は信じているだけ引く接続の作成によってコッピングだため、それ以外のフィードバックを受けていない限り
catching (operation) option
catching (operation) either

:Scalaの型推論の不思議を経て、私は簡潔な実装に取り​​扱う一般的なエラーを抽象化しています、この場合、最も可能性が高いエラー条件)。ここでは新しい実装です:

protected def authNetProcess(params: Map[String,String]) = { 
    connect() match { 
     case Some(conn) => 
     val request = new DataOutputStream(conn.getOutputStream) 
     request.write(getUrlParams(params).getBytes) 
     request.flush() 
     request.close() 
     val response = new BufferedReader(new InputStreamReader(conn.getInputStream)) 
     val results = response.readLine().split("\\|") 
     response.close() 
     results.toList 
     case None => List[String]() 
    } 
    } 

    private def connect() = { 
    lazy val url = if (isDev) new URL(testUrl) else new URL(prodUrl) 
    catching (url.openConnection) option match { 
     case Some(conn) => 
     conn.setDoOutput(true) 
     conn.setUseCaches(false) 
     //conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") 
     Some(conn) 
     case None => None // connection failed 
    } 
    } 

私はより厳格なアプローチがmaybeWorkedオプションの操作にすべての潜在的なエラー条件を抽出し、その後のための理解でそれらのすべてを包むことであろうと仮定します。それはおそらく適切な/責任あるアプローチです...しかし、一日で非常に多くの時間だけ後でこれを再訪します

フィードバックは高く評価されました!親指のルールに

1

スティック:あなたがそれを処理する必要がある場合

だけ例外をキャッチ。

「処理する必要があります」という明確な定義はありませんが、別の例外をスローすることができるため、例外をキャッチする必要があります。

"必要な処理"は、主にアプリケーションの動作やその他の依存関係によって定義されます。

アプリケーションが例外で中止する代わりにエラーを表示する必要がある場合は、それが必須です。

この場合、予告を捕まえても、意味のある処理が追加されます。

APIで別の例外をスローする必要がある場合は必須ですが、APIの定義が正しくない可能性があります。

私はいつも例外を別の例外で置き換えるという付加価値について疑問を呈しています。

あなたの例にこれを適用する:

はそれがauthNetProcessで()接続()から例外をキャッチするためにいくつかの値を追加しますか?

いいえ!その例外をconnect()の内部で処理する方法はありません。だからauthNetProcessの呼び出し側にその例外を残すようにしてください。そこでは、例外の種類に基づいて異なる処理を提供することができます。