2010-10-19 182 views
8

我在这里发现问题Should a retrieval method return 'null' or throw an exception when it can't produce the return value?Should functions return null or an empty object?,但我认为我的情况完全不同。我应该返回null还是抛出异常?

我在写一个由web服务和客户端组成的应用程序。 webservice负责访问数据,并将数据返回给客户端。我设计我的应用程序是这样的:

// web服务

try 
{ 
    DataTable data = GetSomeData(parameter); 
    return data 
} 
catch (OopsException ex) 
{ 
    //write some log here 
    return null; 
} 

//客户端:

DataTable data = CallGetSomeData(parameter); 
    if(data == null) 
    { 
     MessageBox.Show("Oops Exception!"); 
     return; 
    } 

嘛,没有返回null的规则。我不认为我应该重新抛出异常并让客户端捕获SoapException。你对此有何评论?有没有更好的方法来解决这个问题?

谢谢。

+0

例外允许您[收紧您的后置条件](http://stackoverflow.com/q/1744176/54262)。它们也与语言,风格和编码习惯密切相关;但你没有指定任何。 – 2010-10-19 15:33:03

+0

这看起来像是asp.net,我想呢?你应该相应地标记它。 – RMorrisey 2010-10-29 21:26:56

回答

4

在你的情况下,你的web服务中已经抛出了一个异常并以某种方式处理了异常。

返回null有一个好主意,因为客户端代码可以知道在您的Web服务中出现错误。

在客户的情况下,我认为你的方式是好的。我认为没有理由抛出另一个异常(即使您不在Web服务中)。

我这样说,因为从技术上讲,没有什么在您的客户端代码中导致错误。您只是从Web服务获取不良数据。这只是处理来自外部来源的潜在不良投入的问题。个人而言,作为一个经验法则,当我由于客户端代码无法控制这些数据而导致数据不正确时,我会回避抛出异常。

只要确保您处理data == null条件的方式不会导致客户端代码崩溃。

2

我使用的所有Web服务都返回对象,而不是简单的数据类型。这些对象通常包含一个名为Successbool值,可让您快速测试是否信任返回的数据。无论哪种情况,我认为所引发的错误应该是无法接受的(即无意),因此表明服务本身存在问题。

0

处理异常的一般做法是,当正常情况下预期流的顺序时,由于资源不可用或预期输入而无法完成顺序。

在你的情况下,你仍然需要决定你希望你的客户端代码如何对空或异常做出反应。

0

如何在发生任何不良事件时传入要调用的委托?如果这是外部可能想要的,或者让该函数返回null(如果外部代码将检查该内容),或者可能采取其他一些操作,则代表可以抛出异常。根据传递给委托人的信息,它可能能够处理问题条件,以便允许处理继续(例如委托人可能会在被调用的前几次设置“重试”标志,以防片状网络连接预计)。委托人也可能记录异常可能被捕获时不存在的信息。

PS - 最好将自定义类传递给问题检测代理。这样做将允许该方法的将来版本向代理提供附加信息,而不会破坏任何期望更简单信息的实现。

1

我认为这一切都归结为您的客户是否可以使用任何信息为什么没有数据返回的问题。
例如 - 如果由于在GetSomeData中调用的(比如sql)服务器关闭而客户端实际上可以使用该信息做某些事情(例如显示适当的消息),则没有数据返回 - 您不想隐藏那个信息 - 抛出一个错误是更多的信息。
另一个例子 - 如果parameter为空,并且导致一个异常..(尽管你可能应该在代码中早些时候处理过这个问题..但是你明白了) - 应该抛出一个适当的(信息)异常。

如果客户端不关心人,为什么他没有得到任何数据备份,你可以返回null,他会忽略无论如何错误的文字和他的代码看起来是一样..

1

如果你的客户端和服务运行在不同的机器上或者不同的进程上,不可能从服务中抛出一个错误并在客户端捕获它。如果你坚持使用异常,你可以期望的最好的方法是在客户端上检测错误条件(null或其他约定)并重新抛出一个新的异常。

0

在同一个进程空间中推荐使用异常。在整个流程中,只有通过信息才能评估成功/失败。

2

我觉得有可能是进行决策时需要考虑几个因素:

  • 什么是惯用的方式做到这一点在你使用的语言(如果它不是一个web服务)
  • 有多好您的SOAP/Web服务库(它传播完成异常或没有)
  • 什么是客户端的最简单的事情做

我往往使客户最容易做的,惯用的事情,内图书馆的局限性。如果客户端库不关心自动恢复序列化异常,我可能会用一个lib来包装它,这样我就可以执行以下操作。

客户:

try: 
    # Restore Serialized object, rethrow if exception 
    return CallGetSomeData(parameter); 
except Timeout, e: 
    MessageBox.Show("timed out") 
except Exception, e: 
    MessageBox.Show("Unknown error") 
exit(1) 

的WebService:

try: 
    return GetSomeData(parameter) # Serialized 
except Exception, e: 
    return e # Serialized 
4

一般我尝试,他们返回某种指示是否有一个技术/功能的标志设计我的web服务以这样的方式错误与否。 此外,我尝试返回一个复杂的对象结果不只是一个字符串,以便我可以返回像这样的东西:

result-> code =“MAINTENANCE” result-> MaintenanceTill =“2010-10-29 14: 00:00"

所以对于一个Web服务,应该让我dataEntities的名单,我将返回类似:

<result> 
    <result> 
     <Code>OK</Code> 
    </result> 
    <functionalResult> 
     <dataList> 
      <dataEntity>A</dataEntity> 
     </dataList> 
    </functionalResult> 
</result> 

,这样可我的web服务背后发生每一次失败都被隐藏在一个错误的结果。 开发人员在调用我的webservice时必须关心的唯一例外是在webservice之前可能发生的例外或错误。

2

你的第一个问题是“不返回空值的规则”。我强烈建议重新考虑这一点。

返回一个SoapException是一种可能性,但就像hacktick已经提到的那样,使用状态标志{Success,Fail}返回来自Web服务的每个响应的复杂对象会更好。

0
  • 既然你是客户你的web服务,您可以在服务层记录异常和返回null到客户端,但客户还是应该知道,如果CallGetSomeData返回null因为:a)数据不可用,或者b)表被锁定时存在数据库异常。因此,总是很好地知道是什么原因造成了错误,以便在客户端更轻松地进行报告。您应该将错误代码和说明作为消息的一部分。
  • 如果你没有使用你的web服务,那么你应该定义抛出异常,出于上述相同的原因,客户端应该知道发生了什么,并由他们决定如何处理。
+0

你会如何定义“消费你的web服务”? TIA。 – AbdullahC 2010-10-30 01:12:18

+0

“不要使用你的web服务” - “不是你的服务的客户端”。这是当你写一个公共使用的服务,如信用卡认证。 – anivas 2010-10-30 07:39:48