2012-07-15 27 views
3

在考虑到潜在的运行时故障,如数据库查询,似乎是一个必须使用某种形式的Either[String, Option[T]]为了准确地捕捉到以下成果:Scala:是唯一的选择吗?

  1. 一些(发现结果)
  2. 无(没有发现结果)
  3. SQL异常

选项根本没有足够的选择。

我想我需要潜入斯卡拉,但现在它是直的要么,除非我在上面丢失了一些东西。

已经把自己装进了我的DAO实现的一个角落,只使用Either进行写入操作,但现在我发现有些写入依赖于Option读取(例如检查新用户注册时是否存在电子邮件),这是一个主要的糟糕的赌博。

在我全力以赴之前任何人都没有替代解决方案来处理成功/失败/异常的运行时间三连胜吗?

+1

由于记录是一种可能性'或者[String,List [T]]'会更合适,不是吗? – pedrofurla 2012-07-15 00:48:15

+0

取决于,我需要处理选项[T]和列表[T]或选项[列表[T]]。现在我执行[String,SuccessType]进行写操作,除非我另有说明,否则对读操作也会这样做。 – virtualeyes 2012-07-15 01:07:13

+0

@virtualeyes否,你真的不需要处理所有这些。你说有一些记录,没有记录或异常,是否正确?那么一些记录可以是非空的记录列表,没有记录可以是记录的空列表,并且异常像往常一样是左边的任一部分。 – 2012-07-15 06:04:07

回答

4

使用Option[T]的情况下records foundno records found并抛出的SQLException中的情况例外。

只是将异常包装在您自己的异常类型中,如PersistenceException,以便您没有泄漏抽象。

我们这样做是因为我们不能也不想从意外的数据库异常中恢复。在这种情况下,异常会陷入顶层,我们的Web服务会返回500 Internal server error

在我们想恢复的情况下,我们使用scalaz中的Validation,这很像Lift的Box

+1

+1,正在考虑让异常冒泡并让Web服务器生成一个500 ...但Box,Validation或者任一[Fail,Option [T]]提供了对实际出错的更多控制,更不用说事务性通过{...}块查询,你无法使用Option结果类型。 – virtualeyes 2012-07-15 18:45:52

8

尝试从奇妙lift框架Box。它提供了你想要的。

有关详细信息,请参见this wiki(以及顶部的链接)。幸运的电梯项目以及模组化,使用Box唯一的依赖是net.lift-web % lift-common

+0

+1谢谢,Box和Either [Fail,Option [T]]之间有什么区别?推测盒子更容易与... – virtualeyes 2012-07-15 01:21:47

+2

以及你写的东西少:D。 Box是Monad,因此可以方便地检索三种状态中的任何一种或与其他方框组合。要查看Box如何运行您可以从[cheatsheet]开始(http://nerd.kelseyinnis.com/blog/2012/05/16/box-cheat-sheet-for-lift/) – xiefei 2012-07-15 01:22:18

+0

伟大的链接,太糟糕了作者尚未撰写他在Box上提及的文章,以便理解。我对{...}查询事务块使用Either Right预测,这是一个很棒的保护措施。对Box做同样的事情会很好...... – virtualeyes 2012-07-15 13:40:27

0

这里是我的修订办法

保留或者(在这里我们要回滚对修真左结果对于事务块有用)返回的查询写操作。但是,对于选项返回查询读取,而不是吞下与None(并记录它)的异常,我创建了一个500错误屏幕,让异常冒泡。

为什么不处理类似查询异常的运行时失败时默认使用任一结果类型?选项[T]读取与vs [Why-Fail,Option [T]]一起工作会更方便一些,您必须折叠/映射以获取T.Leaving要么写操作简化了事情(更重要的是所以鉴于这是应用程序目前的设置,不需要重构;-))

唯一需要的其他更改是AJAX请求。我们检查状态类型并相应地显示500错误消息,而不是在AJAX状态div容器中显示整个500错误页面响应。

if(data.status == 500) 
    $('#status > div').html("an error occurred, please try again") 

大概可以发送响应之前做一个isAjax检查服务器端;在这种情况下,我只能发送状态+消息而不是错误页面本身。