Какая строка (и) этого кода может выдать исключение «Индекс был за пределами массива»? - PullRequest
2 голосов
/ 02 декабря 2009

Небольшая предыстория этой ошибки: клиент, получивший это сообщение об ошибке в своем журнале и службе поддержки, еще не смог его воспроизвести. Поэтому я проверяю код, пытаясь определить, что может происходить. Я сузил его до этого раздела кода, просмотрев их файл журнала. Я не писал этот код, но его цель - загрузить zp-файл на удаленный сервер. Так что вопрос ...

Какими строками этот код может выдать исключение "Индекс был за пределами массива"?

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;

}

Заранее спасибо!

UPDATE: Я думаю, что мы все в значительной степени согласны, что проблема будет в FTPLib, я посмотрю, есть ли у нас источник для этого. Я обнаружил, что это неясная ошибка, которую покупатель даже не может воспроизвести последовательно, так что это будет забавно. Я добавил дополнительное ведение журнала отладки с использованием функций Exception.StackTrace и Exception.ToString. Я обновлю еще раз, как только проблема будет решена, и постараюсь наградить правильного человека правильным ответом, хотя все сделали хорошие предложения. Спасибо за помощь!

Ответы [ 7 ]

2 голосов
/ 02 декабря 2009

Я предлагаю вам зарегистрировать Exception.StackTrace в том месте, где вы в данный момент перехватываете исключение вне границ. Exception.ToString () также очень полезен, так как дает большую часть важной информации. Это должно сказать вам точное место, где выдается исключение (без необходимости угадывать). Остерегайтесь, однако, кода, который перехватывает исключение и скрывает его - я вижу, что опубликованный вами код имеет "catch (IOException) {}". Также остерегайтесь кода, который перехватывает исключение, а затем выдает другое исключение, которое замаскирует исходную ошибку.

Не должно быть необходимости заключать в команду try ... перехватывать отдельные подозрительные строки - если какое-то исключение перехватывается в некоторой точке цепочки вызовов и регистрируется.

2 голосов
/ 02 декабря 2009

Не зная остальной код, это может быть довольно сложно сказать. Линия, которая выделяется для меня:

ff.getLastMessage()

но это только обоснованное предположение (если, например, сообщения хранятся в массиве или симлиаре и последние извлекаются из этого)

1 голос
/ 02 декабря 2009

В дополнение к посту Уилла ради полноты:

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 написаны кем-то, кто не знает, что происходит или плохо написано, посмотрите на метод входа в систему - все в нижнем регистре, как упомянуто выше Уиллом (спасибо за указание).

Надеюсь, что это поможет и счастливой охоте на жуков ... С наилучшими пожеланиями, Том.

1 голос
/ 02 декабря 2009

Ничего очевидного. Это сводится к фактической реализации FtpFactory (мой голос за вероятную причину) и журналу.

Фабрика может хранить массив экземпляров того типа, который она создает, если создание этих типов является дорогостоящим. Поэтому в первый раз, когда вы делаете что-то, что может потребовать использования одного из этих экземпляров ("ff.login"), вы можете обнаружить ошибку.

Я бы посоветовал вам окружить любую попытку использовать фабрику попробовать / поймать и записать в журнал, где это происходит. Кроме того, я бы предложил в любом случае избегать использования этой фабрики, потому что она написана кем-то, мало заботящимся о стандартах и ​​методах (имена методов в нижнем регистре?), Что является предупреждающим признаком плохого качества изготовления.

tl; dr: Не доверяйте своей фабрике ftp. Это, наверное, отстой.

1 голос
/ 02 декабря 2009
ff.getLastMessage()

Что делает этот метод? Как оно получает последнее сообщение? Если он использует что-то вроде messages[messages.Count - 1] или что-то подобное, а коллекция сообщений пуста, это приведет к ошибке Это было бы моим лучшим предположением.

1 голос
/ 02 декабря 2009

Я не думаю, что это какая-то из этих строк кода.

Моим первым предположением было бы что-то в вашем цикле foreach , но это выглядит довольно солидно.

Вы уверены, что это часть кода?

Можете ли вы вставить трассировку стека?

0 голосов
/ 03 декабря 2009

В принципе, каждый отдельный вызов метода является возможным кандидатом, включая конструктор и свойства. (В основном это вызовы методов), хотя последние два, вероятно, с наименьшим риском (Это было бы странной реализацией любого из них)

наиболее правдоподобно сказать, что это ff.getLastMessage ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...