Exception 我应该返回null还是抛出异常?

Exception 我应该返回null还是抛出异常?,exception,exception-handling,return-value,Exception,Exception Handling,Return Value,我在这里发现了问题,但我认为我的情况完全不同 我正在编写一个由Web服务和客户端组成的应用程序。webservice负责访问数据,并将数据返回给客户端。我的应用程序设计如下: //网络服务 try { DataTable data = GetSomeData(parameter); return data } catch (OopsException ex) { //write some log here return null; } //客户: DataTab

我在这里发现了问题,但我认为我的情况完全不同

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

//网络服务

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。你对此有何评论?有没有更好的方法来解决这个问题


谢谢。

在您的情况下,已经在web服务中以某种方式引发并处理了异常

返回null是一个好主意,因为客户机代码可以知道web服务中出现了错误

就客户而言,我认为你的方式很好。我认为没有理由抛出另一个异常(即使您不再使用web服务)

我这样说是因为,从技术上讲,没有任何东西导致您的客户机代码出现错误。您只是从web服务中获取了错误数据。这只是处理来自外部源的潜在错误输入的问题

就个人而言,根据经验,当我得到坏数据时,我会避免抛出异常,因为客户机代码无法控制它


只要确保处理
data==null
条件时不会使客户端代码崩溃。

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

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


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

在发生任何不好的事情时,传入一个要调用的委托怎么样?如果外部希望抛出异常,委托可以抛出异常,或者让函数返回null(如果外部代码将对此进行检查),或者可能采取其他操作。根据传递给代理的信息,它可能能够以允许处理继续的方式处理问题条件(例如,代理可能在调用它的前几次时设置“重试”标志,以防出现不稳定的网络连接)。代理也可以记录在捕获异常时不存在的信息


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

我认为这一切归结为一个问题,即您的客户是否可以使用任何信息来解释为什么没有返回数据。
例如,如果由于在
GetSomeData
中调用的(比如sql)服务器关闭而没有返回任何数据,并且客户端实际上可以使用该信息执行某些操作(例如,显示适当的消息)-您不想隐藏该信息-抛出错误会提供更多信息。
另一个示例-如果
参数
为空,则会导致异常。。(虽然您可能应该在代码的前面考虑到这一点……但是您知道了)-应该抛出一个适当的(信息性的)异常


如果客户机根本不关心他为什么没有返回任何数据,您可能会返回null,他无论如何都会忽略错误文本,他的代码看起来是一样的。

如果您的客户机和服务运行在不同的机器或不同的进程上,则不可能从服务抛出错误并在客户机上捕获它。如果您坚持使用异常,您最好希望客户端上有一些代理来检测错误条件(null或其他约定)并重新引发新异常。

建议在同一进程空间中使用异常。在整个流程中,只有通过信息才能评估成功/失败
  • 在您所使用的语言中(如果不是Web服务),实现这一点的惯用方法是什么
  • 您的soap/webservice库有多好(它是否支持异常)
  • 客户最容易做的事情是什么
我倾向于让客户在库的限制范围内做最简单、惯用的事情。如果客户机库不负责自动恢复序列化异常,我可能会用一个这样做的库来包装它,这样我就可以执行以下操作

客户:

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)
网络服务:

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

一般来说,我尝试以这样的方式设计Web服务:它们返回某种标志,指示是否存在技术/功能错误。 此外,我尝试为结果返回一个复杂对象,而不仅仅是一个字符串,这样我就可以返回如下内容:

结果->代码=“维护” 结果->维护TILL=“2010-10-29 14:00:00”

因此,对于应该为我提供数据实体列表的Web服务,我将返回如下内容:

<result>
    <result>
        <Code>OK</Code>
    </result>
    <functionalResult>
        <dataList>
            <dataEntity>A</dataEntity>
        </dataList>
    </functionalResult>
</result>
因此,我的Web服务背后可能发生的每一个失败都隐藏在错误结果中。 开发人员在调用my webservice时必须关心的唯一异常是在webservice之前可能发生的异常或错误。

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

返回SoapException是可能的,但与hacktick al一样