我有一个名为connect的函数,如下所示:
public boolean connnect(){
{
..... connecting codde
if(connectionSuccessfull)
{
return true;
}
else
{
return false;
}
}
这是一种非常基本的错误处理形式,我想升级此函数以正确处理错误。比如告诉我 false 有错误,但可以说,错误,身份验证失败或超时错误等。 然后需要将此信息发送回调用者,以便知道发生了什么。
这样做的正确方法是什么?
{编辑} 在我看来,很可能会发生异常,我会说50%的时间。
我想出了这个,看起来部分正确吗?
namespace MobileWebServices.Exceptions
{
//Timeout
public abstract class TimeOutException : Exception
{
}
public class ConnectingTimeOutException : TimeoutException
{
}
public class DissconnectingTimeOutException : TimeoutException
{
}
//Authetntication
public abstract class AuthenticationException : Exception
{
}
public class BadAuthenticationException : AuthenticationException
{
}
}
答案 0 :(得分:2)
正常的方法是抛出异常(perhaps of a user-defined type),然后在更高级别捕获这些异常。
如果出于某种原因你不能使用异常,你可以编写一个包含错误消息的包装类(如果没有错误则为null)和bool
结果(只有在错误消息为null)。
但是,我建议使用例外。 (唯一的问题可能是您是否需要在异常中全局化错误消息字符串,但是the consensus is that you should not。)
答案 1 :(得分:2)
有些事情:
public void Connect()
{
try
{
//code here to look-up the connection details
if(!ValidateConnectionDetails(details))
throw new InvalidOperationException("The connection details are not valid.");
//code here to establish the connection
if(SomeTestThatShowsWereNotHappyWithTheConnection())
throw new Exception("The connection is bad, for some reason");
}
catch(SocketException se)
{
//We'd only have this block if a socket exception is possible. We might just allow it to pass on up.
throw; // User now gets the exception we got, exactly.
//We might re-throw the error, but from here so the stack-trace goes to here rather than the innards of this method:
throw se;
//Most usefully we might throw a new exception that contains this as an inner exception:
throw new Exception("Connecting failed", se);
//Or even better, we might throw a more well-defined exception, that relates to this operation more specifically, with or without the inner exception, depending on whether that is likely to be useful:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor");
//OR:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor", se);
}
catch(Exception ex)
{
//If we get to an exception ourselves that isn't of a particular type we're expecting, we probably shouldn't catch it at all. We might though want to note the exception before re-throwing it, or throw a more specific connection with this as an inner-exception:
Log(ex);
throw;
}
}
由于您不再返回值来表示成功,因此您现在还可以返回表示您创建的连接的对象:
public ConnectionObject Connect()
{
// Much as above, but returning the object before the end of the `try`.
}
只有在可能发生故障的情况下才会返回表示失败的值,并且您希望调用代码能够在调用时合理地做出反应。这不可能与代码连接,因为调用代码可能是代码,例如,代码。连接然后进行操作,而调用的代码又是应该捕获异常(无论是从这里还是后续操作)的地方 - 它是最终关心失败的代码。
在后一种情况下,返回表示失败的值会更有意义。在这里,我可能仍然会考虑一个异常,因为它可以封装更多信息,编码器以正常的方式使用其他.NET方法,并且因为调用代码可能不是书面思考"尝试获得连接,然后如果它工作..."它的书面思维"得到连接然后......"错误的情况就是这样;错误案例。 (为了进行比较,像int.TryParse()
这样的方法是回答问题"这个字符串是否代表一个整数,如果是,它是什么?"方法int.Parse()
回答了问题"这个字符串中的整数是多少?"没有整数是错误条件。)
以另一种方式来思考。您目前是否正在使用网络浏览器浏览网页,或者您是否正在使用它来尝试浏览网页?您的互联网连接可能会死于您,阻止您继续阅读这些答案,但您认为这是您尝试做的问题。
答案 2 :(得分:1)
以下是有关如何完成工作的示例:
首先使用connect()方法返回一个对象(例如Socket)
如果连接失败而没有抛出异常,则返回null
在你的connect()方法中,尝试/捕捉你的连接指令,并重新抛出那些被捕获的指示
然后在调用方法中,捕获所有可抛出的异常,并检查返回的对象是否为null。
以下是使用套接字的代码示例:
public static Socket connect()
{
Socket s = null;
try
{
IPEndPoint iEP = new IPEndPoint("127.0.0.1", 8080);
s = new Socket(iEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s.Connect(iEP);
if(!s.Connected)
{
return null;
}
}
catch(Exception e)
{
throw e;// Rethrow the Exception to the caller
}
return s;
}
public static void Main(String[] args)
{
Socket mySocket = null;
try
{
mySocket = connect();
}
catch(SocketException e)
{
// TODO - Detailed error about a SocketException
Console.Error.WriteLine("SocketException: " + e.Message + "(" + e.ErrorCode + ")");
}
catch(SecurityException e)
{
// TODO - Detailed error about a SecurityException
Console.Error.WriteLine("SecurityException: " + e.Message);
}
catch(Exception e)
{
// TODO - Detailed error about those Exceptions :
// ArgumentNullException, ObjectDisposedException and InvalidOperationException
Console.Error.WriteLine(e.GetType() + ": " + e.Message);
}
if(mySocket == null)
{
// TODO - Error while initializing the Socket
Console.Error.WriteLine("Error while initializing the Socket");
}
// TODO - Use your Socket here
}
答案 3 :(得分:0)
我认为最好的方法是使用围绕您的调用的try catch异常,并使用您想要的异常:
catch(TimeoutException ex)
{
//Do something
}
catch(SqlException ex)
{
//do something
}
//....
catch(Exception ex)
{
//do something
}
确保捕获的顺序(最后的全局异常)