这段代码可能抛出哪一行“索引超出了数组的范围”异常?

时间:2009-12-02 16:03:50

标签: c# arrays exception

有关此错误的一点背景:客户在其日志文件中获取此错误消息并且支持尚未能够重现它。所以我正在审查代码,试图确定可能发生的事情。我通过查看他们的日志文件将其缩小到代码的这一部分。我没有写这段代码,但它的目的是将一个zip文件ftp到远程服务器。所以问题是......

这段代码可能会抛出“索引超出数组范围”的异常?

FtpLib.FTPFactory ff = new FtpLib.FTPFactory();
try

{
    ff.setRemoteHost(job.FTPHost);
    ff.setRemoteUser(job.FTPUser);
    ff.setRemotePass(job.FTPPW);
    ff.login();
// Execute misc. extra commands
foreach (string command in job.Commands)
{
    if (log.IsDebugEnabled)
        log.Debug("JOB: " + job.ID + " --    FTP Command \"" + command + "\" sent...");

    ff.sendCommand(command);

    if (log.IsDebugEnabled)
        log.Debug("JOB: " + job.ID + " --       Response: " + ff.getLastMessage());
}

try
{
    ff.mkdir(job.FTPRemoteDir);
}
catch (IOException) { }

ff.chdir(job.FTPRemoteDir);
ff.setBinaryMode(true);

if (log.IsInfoEnabled)
    log.Info("JOB: " + job.ID + " --    FTP UPLOAD: \"" + zipfile.Name + "\" to \"" + job.FTPHost + "/" + job.FTPRemoteDir + "/\"");
ff.upload(zipfile.FullName);
if (log.IsInfoEnabled)
    log.Info("JOB: " + job.ID + " --       Completed.");

bFTPSuccess = true;
break;

}

提前致谢!

更新: 我想我们都非常同意这个问题将出现在FTPLib中,我会看看我们是否有源代码。我发现这是一个模糊的错误,客户甚至无法一致地重现,所以这将是一个有趣的一针点。我使用Exception.StackTrace和Exception.ToString函数添加了额外的调试日志记录。一旦问题解决了,我会再次更新并尝试用正确答案给予正确的人,尽管每个人都提出了很好的建议。谢谢你的帮助!

7 个答案:

答案 0 :(得分:2)

不知道其他代码可能很难分辨。对我而言最突出的是:

ff.getLastMessage()

但这只是一个有根据的猜测(例如,如果消息存储在数组或simliar中,以及最后的摘录)

答案 1 :(得分:2)

我建议您在当前捕获越界异常的位置记录Exception.StackTrace。 Exception.ToString()也非常有用,因为它提供了大部分重要信息。这应该告诉你抛出异常的确切位置(无需猜测)。但要注意捕获异常并隐藏它的代码 - 我看到你发布的代码有“catch(IOException){}”。还要警惕捕获异常的代码,然后抛出一个不同的异常,这将掩盖原始错误。

只要在调用链中的某个点捕获并记录任何异常,就不应该需要包含try ... catch单个可疑行 -

答案 2 :(得分:1)

我不认为这是任何一行代码。

我的第一个猜测是你的 foreach 循环中的内容,但这看起来非常可靠。

你确定这是代码的一部分吗?

可以粘贴堆栈跟踪吗?

答案 3 :(得分:1)

ff.getLastMessage()

这种方法有什么作用?它是如何得到最后一条消息的?如果它使用messages[messages.Count - 1]或类似的东西,并且消息集合为空,则会抛出该错误。那是我最好的猜测。

答案 4 :(得分:1)

没什么明显的。它将归结为FtpFactory(我的可能原因投票)和日志的实际实现。

如果创建这些类型的代价很高,工厂可能会保留它创建的类型的实例数组。因此,当您第一次执行可能需要使用其中一个实例(“ff.login”)的操作时,可能会暴露该错误。

我建议你将任何使用try / catch工厂的尝试包围起来,并在日志中记录它。另外,我建议不要使用那个工厂,因为它是由一个很少考虑标准和做法的人写的(小写方法名称?),这是工艺不佳的警示标志。

tl;博士:不要相信你的ftp工厂。它可能很糟糕。

答案 5 :(得分:1)

除了Will的帖子之外,为了完整性:

FtpLib.FTPFactory ff = null;
try
{
    ff = new FtpLib.FTPFactory();
}
catch(Exception ex)
{
    // Log it
}

另外,我不禁想知道,登录是否有效,这是另一个在try / catch块中包装它的地方

try
{
    ff.login();
}
catch(Exception ex)
{
   // Log it.
}

可能是登录失败了,ff正用于执行命令并可能抛出异常 - 不要问为什么?我怀疑这个FTP例程是由一个不知道发生了什么或写得不好的人编写的,请看一下登录方法 - 所有小写字母都是上面提到的(赞成指出来)。

希望这有助于快乐寻找虫子... 最好的祝福, 汤姆。

答案 6 :(得分:0)

基本上每个方法调用都是可能的候选者,包括构造函数和属性。 (它们基本上是方法调用)最后两个虽然可能是那些风险最低的(这可能是一个奇怪的实现)

我认为最合理的是ff.getLastMessage()