LINUX.ORG.RU

[TCL] tcllib ftp не могу поймать ошибку

 


0

1

Передаю через $file 3 пути к объекту (заведомо не существующих), что бы узнать их размер (если они будут когда-нибудь будут лежать на фтп)

foreach file $files {
    regexp -all $RE $file file file_path
    set ABC [catch {ftp::FileSize $token  $file_path} file_size_remote]
    puts $ABC
}

Отсутствие первого файла ловится нормально (ABC1), а далее валятся ошибки и catch всегда возвращает 0. Почему так?

ABC 1
error     error | E: Error getting file size!:
error     can't read "errorInfo": no such variable
error         while executing
error     "log::log error "$state | E: $msg:\n$errorInfo""
error         (procedure "DisplayMsg" line 24)
error         invoked from within
error     "DisplayMsg $s $errmsg error"
error         (procedure "WaitOrTimeout" line 17)
error         invoked from within
error     "WaitOrTimeout $s"
error         (procedure "ftp::FileSize" line 24)
error         invoked from within
error     "ftp::FileSize $token $file_path"
ABC 0
error     error | E: Error getting file size!:
error     can't read "errorInfo": no such variable
error         while executing
error     "log::log error "$state | E: $msg:\n$errorInfo""
error         (procedure "DisplayMsg" line 24)
error         invoked from within
error     "DisplayMsg $s $errmsg error"
error         (procedure "WaitOrTimeout" line 17)
error         invoked from within
error     "WaitOrTimeout $s"
error         (procedure "ftp::FileSize" line 24)
error         invoked from within
error     "ftp::FileSize $token $file_path"
ABC 0

::ftp::FileSize handle file

This command returns the size of the specified file on the ftp server. If the command fails an empty string is returned.

ATTENTION! It will not work properly when in ascii mode and is not supported by all ftp server implementations.

Может поэтому?

qaqa ★★
()
Ответ на: комментарий от qaqa

не похоже, с ::ftp::Cd к примеру , те же проблемы

macumazan ★★
() автор топика
Ответ на: комментарий от qaqa

Посмотрел внимательнее...

Здесь какая то каша:

set ABC [catch {ftp::FileSize $token  $file_path} file_size_remote]

Я бы сделал как то так:

if {catch {set file_size_remote [ftp::FileSize $token  $file_path]}} {
    puts "файл: $file_path"
    puts "описание ошибки: $::errorInfo"
    puts "код ошибки: $::errorCode"
}

qaqa ★★
()
Ответ на: комментарий от qaqa

Прошу прощения, скобки квадратные в if {...} забыл.

if {[catch {set file_size_remote [ftp::FileSize $token  $file_path]}]} {
    puts "файл: $file_path"
    puts "описание ошибки: $::errorInfo"
    puts "код ошибки: $::errorCode"
}

qaqa ★★
()
Ответ на: комментарий от qaqa

Добавил if {! [catch , иначе условие не выполнялось. Получается, catch считает, что проблемы нет.

Вывод такой получается

error     error | E: Error getting file size!:
error     can't read "errorInfo": no such variable
error         while executing
error     "log::log error "$state | E: $msg:\n$errorInfo""
error         (procedure "DisplayMsg" line 24)
error         invoked from within
error     "DisplayMsg $s $errmsg error"
error         (procedure "WaitOrTimeout" line 17)
error         invoked from within
error     "WaitOrTimeout $s"
error         (procedure "ftp::FileSize" line 24)
error         invoked from within
error     "ftp::FileSize $token  $file_path"
файл: test1
описание ошибки: can't read "errorInfo": no such variable
    while executing
"log::log error "$state | E: $msg:\n$errorInfo""
    (procedure "DisplayMsg" line 24)
    invoked from within
"DisplayMsg $s $errmsg error"
    (procedure "WaitOrTimeout" line 17)
    invoked from within
"WaitOrTimeout $s"
    (procedure "ftp::FileSize" line 24)
    invoked from within
"ftp::FileSize $token  $file_path"
код ошибки: NONE
error     error | E: Error getting file size!:
error     can't read "errorInfo": no such variable
error         while executing
error     "log::log error "$state | E: $msg:\n$errorInfo""
error         (procedure "DisplayMsg" line 24)
error         invoked from within
error     "DisplayMsg $s $errmsg error"
error         (procedure "WaitOrTimeout" line 17)
error         invoked from within
error     "WaitOrTimeout $s"
error         (procedure "ftp::FileSize" line 24)
error         invoked from within
error     "ftp::FileSize $token  $file_path"
файл: fold/test3
описание ошибки: can't read "errorInfo": no such variable
    while executing
"log::log error "$state | E: $msg:\n$errorInfo""
    (procedure "DisplayMsg" line 24)
    invoked from within
"DisplayMsg $s $errmsg error"
    (procedure "WaitOrTimeout" line 17)
    invoked from within
"WaitOrTimeout $s"
    (procedure "ftp::FileSize" line 24)
    invoked from within
"ftp::FileSize $token  $file_path"

macumazan ★★
() автор топика
Ответ на: комментарий от macumazan

Добавил if {! [catch , иначе условие не выполнялось.

Без комментариев :D

Тут походу внутрях у ::ftp::FileSize свой catch, раз в ::errorInfo не пусто, а код ошибки NONE.

This command returns the size of the specified file on the ftp server. If the command fails an empty string is returned. ATTENTION! It will not work properly when in ascii mode and is not supported by all ftp server implementations.

Когда при выполнении команды ::ftp::FileSize возникает ошибка, возвращается пустая строка. Но, это означает, что размер выяснить не удалось. Такое, естественно, может быть даже если файл есть (смотри Attention). Правильно в данном случае получать список файлов и делать в нем поиск.

Но если работает и так, тогда:

set file_size_remote [ftp::FileSize $token  $file_path]
if {$file_size_remote == ""} {
    puts "ошибка получения размера файла: $file_path" 
}

qaqa ★★
()
Ответ на: комментарий от qaqa

Казалось бы все верно, но как тогда понимать

can't read "errorInfo": no such variable
    while executing
"log::log error "$state | E: $msg:\n$errorInfo""
    (procedure "DisplayMsg" line 24)
    invoked from within
"DisplayMsg $s $errmsg error"
    (procedure "WaitOrTimeout" line 17)
    invoked from within
"WaitOrTimeout $s"
    (procedure "ftp::FileSize" line 24)
    invoked from within
"ftp::FileSize $token  $file_path"
    invoked from within
"set file_size_remote [ftp::FileSize $token  $file_path]"
    (file "./ftp.tcl" line 90)
macumazan ★★
() автор топика
Ответ на: комментарий от qaqa

Ну, возможно это ответ на мой вопрос, но тем не менее не понятно: каким образом мне сделать так, что бы я сам мог обрабатывать ситуацию, когда на ftp нет указанного файла? Вот вижу

set file_size_remote [ftp::FileSize $token  $file_path]
казалось бы вот оно... но не понятно, почему на этом валится

macumazan ★★
() автор топика
Ответ на: комментарий от qaqa

Ну главная мысль в моем первом посте: как при трех одинаковых условиях получаются не одинаковые результаты? Проверено было на ::ftp::FileSize и ftp::Cd

macumazan ★★
() автор топика
Ответ на: комментарий от macumazan

В общем не могу понять до конца, в чем конкретно ваша проблема. Есть подозрение что смущает то, что в stdout присутствуют строки с сообщениями об ошибках. Пакет ftp в стандартный вывод пишет перехваченные ошибки (см DisplayMsg), что действительно вносит некоторую путаницу. Можно задать свою команду для печати ошибок, например, в файл. Раньше я этим пакетом не пользовался, как то не нужно было. Ради интереса поковырял чуток:

package require ftp

set ::debugLog  ~/myftpclient_debug.log
set ::errorLog  ~/myftpclient_error.log

proc ::writeToLog {filename text} {
    set fd [open $filename w]
    puts $fd $text
    close $fd
}

proc ::displayMsg {s msg {state ""}} {
    namespace upvar ::ftp ::ftp$s ftp

    if { ([info exists ftp(Output)]) && ($ftp(Output) != "") } {
        eval [concat $ftp(Output) {$s $msg $state}]
        return
    }

    global errorInfo
    switch -exact -- $state {
        data    {::writeToLog $::debugLog "$state | $msg"}
        control {::writeToLog $::debugLog "$state | $msg"}
        error   {::writeToLog $::errorLog "$state | E: $msg:\n$errorInfo"}
        default {::writeToLog $::debugLog "$state | $msg"}
    }
    return
}

set ::ftp::VERBOSE 0
 
set ftpAddr ftp.ubuntu.com
set h [::ftp::Open $ftpAddr anonymous fake@emale.addr -mode passive -output ::displayMsg]
set dir /ubuntu/dists/oneiric/
set fileName Contents-amd64.gz

set flag 0
foreach item [::ftp::List $h $dir] {
    # если не каталог && имена совпадают
    if {[string index [lindex $item 0] 0] != "d" && [lindex $item end] == $fileName} {
        set fileSize [::ftp::FileSize $h ${dir}${fileName}]
        if {$fileSize != ""} {
            puts "размер файла: $fileSize"
        } else {
            puts "ошибка получения размера файла!"
        }
        set flag 1
        break
    }
}

if {!$flag} {
    puts "файл не найден!"
}

::ftp::Close $h

qaqa ★★
()
Ответ на: комментарий от macumazan

Более корректно:

package require ftp

set ::debugLog  ~/myftpclient_debug.log
set ::errorLog  ~/myftpclient_error.log

proc ::writeToLog {filename text} {
    set fd [open $filename w]
    puts $fd $text
    close $fd
}

proc ::displayMsg {s msg {state ""}} {
    namespace upvar ::ftp ftp$s ftp

    if { ([info exists ftp(Output)]) && ($ftp(Output) != "") } {
        eval [concat $ftp(Output) {$s $msg $state}]
        return
    }

    global errorInfo
    switch -exact -- $state {
        data    {::writeToLog $::debugLog "$state | $msg"}
        control {::writeToLog $::debugLog "$state | $msg"}
        error   {::writeToLog $::errorLog "$state | E: $msg:\n$errorInfo"}
        default {::writeToLog $::debugLog "$state | $msg"}
    }
    return
}

set ::ftp::VERBOSE 0
 
set ftpAddr ftp.ubuntu.com
set h [::ftp::Open $ftpAddr anonymous fake@email.addr -mode passive -output ::displayMsg]

if {$h == -1} {
    error "ошибка подключения к $ftpAddr"
}

set dir /ubuntu/dists/oneiric/
set fileName Contents-amd64.gz

set lsResult [::ftp::List $h $dir]

if {$lsResult != ""} {
    set flag 0
    foreach item $lsResult {
        # если не каталог && имена совпадают
        if {[string index [lindex $item 0] 0] != "d" && [lindex $item end] == $fileName} {
            set fileSize [::ftp::FileSize $h ${dir}${fileName}]
            if {$fileSize != ""} {
                puts "размер файла: $fileSize"
            } else {
                puts "ошибка получения размера файла!"
            }
            set flag 1
            break
        }
    }

    if {!$flag} {
        puts "файл не найден!"
    }   
} else {
    puts "ошибка чтения списка файлов с сервера!"
}

::ftp::Close $h

qaqa ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.