Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice: catching failure points in java.net.URL

New to the JVM, working with Scala and Play 2.0

I'm converting a legacy application over to Play, one that requires payment processing via Authorize.net. Looking through java.net.URL source, there are numerous potential points of failure. Given the interface I've written below, where would you implement try/catch blocks? I'll need to adapt method signatures accordingly, probably returning an Either[Error, Success] to calling client code

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     -> "...",
    ...
  )
}
like image 216
virtualeyes Avatar asked Jun 01 '12 10:06

virtualeyes


1 Answers

Stick to the thumb rule:

Only catch an exception if you must handle it.

There is no sharp definition for "must handle" but it means you should resist the urge to catch an exception because you can just to throw a different exception.

The "must handle" is mainly defined by how your application should work or other dependencies.

If the application requires to display an error to the user instead of aborting with an exception, then it's a must.

In that case catching the excpetion adds also some meaningful processing.

If an API requires to throw a different exception, then it's a must, but the APIs definition is possibly not sound.

I am always questioning the added value of replacing an exception with just another exception.

Applying this to your example:

Would it add some value to catch an exception from connect() in authNetProcess()?

No! There is no way to handle that exception inside of connect(). So its ok to leave that exception to the caller of authNetProcess. There you could provide different handling based on the kind of the exception.

like image 169
bebbo Avatar answered Oct 16 '22 00:10

bebbo