2012-06-01 51 views
10

新的JVM,Scala的工作和播放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

編輯
好吧,如果連接/流過程的任何部分出現故障,交易被大清洗,太傻,只採集上的錯誤連接的開放。我只是包裹在一個catching (operation) option塊整個事務,並在該離開它;我不是太在意回覆:錯誤的確切原因(不管它是被記錄),因爲它是短暫的,所以抓住它,讓用戶再次嘗試;如果錯誤仍然存​​在,請聯繫我們......

ORIGINAL OK,很好,給出的選票和缺乏評論最新的,我能得出的唯一結論是......沒有人在這裏知道他們」什麼重做!嘿嘿,哈哈,開玩笑;-)

雖然我是新來的JVM中,的try/catch /終於膨脹是越來越老的快;通過Scala的類型推斷的奇蹟,我抽離一般的錯誤處理成簡潔的實現:
catching (operation) option
catching (operation) either

除非我收到的反饋,否則,現在我被抓剛創建連接柯平了(我相信,在這種情況下,最可能的錯誤條件)。這裏是新的實現:

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需要拋出一個不同的異常,那麼這是必須的,但是APIs定義可能並不健全。

我總是質疑用另一個異常替代異常的附加價值。

應用到您的示例:

難道增加一些價值可以捕捉到異常連接()在authNetProcess()?

不!無法處理connect()中的異常。所以它可以把這個異常留給authNetProcess的調用者。在那裏你可以根據異常的種類提供不同的處理。