Object Variable Not Set при выполнении агента

Тема в разделе "Lotus - Администрирование", создана пользователем dozer, 13 окт 2009.

  1. dozer

    dozer Гость

    Добрый день!

    У нас на сервере Lotus Domino 6.5.4 работает документооборот. В одной из баз ежедневно выполняется агент - по определенному критерию делает выборку из всех документов и вносит в поля этих документов изменения. Однако недавно этот агент перестал отрабатывать. В дизайнере смотрю свойства агента - там написано, что он запустился во столько-то, закончился во столько-то. Захожу в log.nsf и смотрю там сообщения. Оказывается, через некоторое время после запуска агента выдается такое сообщение:
    AMgr: Agent ('agent_name' in 'db_name') error message: Object variable not set
    На этом все. И такая беда происходит каждый день, т.е. агент затыкается на одном и том же документе, как я понимаю. Но вопрос в том, как же найти, что это за документ, где именно он останавливается...

    Есть ли какие-то варианты? Может нужно что-то дописать в сам агент, чтобы при некорректном завершении, он выдавал ID поврежденного документа?
     
  2. allex

    allex Гость

    Пройтись дебагером в агенте не пробовали ?
    Покажите код агента.
     
  3. ToxaRat

    ToxaRat Чёрный маг
    Lotus team

    Регистрация:
    6 ноя 2007
    Сообщения:
    3.047
    Симпатии:
    18
    это называется обработчик ошибок
    вначале агента пишешь
    on error goto err1
    .....
    .....
    твой существуйщий код
    ....
    ....
    exit sub

    err1:
    print "Err=" & err & ", Error=" & error & ", Line=" & erl
    exit sub

    получишь место в каком происходит ошибка при желании добавишь в принт и ИД проблемного дока
     
  4. dozer

    dozer Гость

    allex, я раньше с дизайнером дел не имел, поэтому пока ничего не пробовал. Сейчас сделал копию БД на локальный комп, буду на ней эксперементировать.
    Как именно пройтись дебагером? Пока что-то не нашел...
    Вот код агента:
    ToxaRat, я вставил эти строки после первой и перед последней в своем агенте (текст агента в предыдущем сообщении) и прогнал его еще раз. Вот что получил в ответ:
    Что не так? И как именно добавить туда ID документа?
     
  5. allex

    allex Гость

    А вот такая конструкция для чего ?
    Код (Text):
    Set tempdoc = dc.GetNextDocument (doc)
    Delete doc
    Set doc = tempdoc
    Сразу Set doc = dc.GetNextDocument (doc) нельзя ?

    Вот тут я так понимаю ты архивируешь респонсы, а если их нет ?
    Код (Text):
    If ExpDays > 0 Then
    Call ArcResp (doc)

    Код (Text):
    print "Err=" & err & ", Error=" & error & ", Line=" & erl &" при обработке док. с UI" & doc.UniversalID
     
  6. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    1. понимаю, что вопрос не к вам, но зачем сперва искать документы, а потом брать необработанные агентом?
    Собственно, это о строчках:
    Код (Text):
    Set dc = db.Search(search$, Nothing, 0)
    Set dc = db.UnprocessedDocuments
    Какой у агента Target установлен - все документы в БД?
    2. добавить после получения перед обработкой документа проверку - никогда не помешает:
    Код (Text):
    if doc.IsValid and not doc.isdeleted and not isEmpty(doc.Items) then
    поможет, если агент сбивается на каком-то конкретном документе
    3. убедиться, что в профайле есть данный итем, перед его получением:
    Код (Text):
    if profile.hasItem("SettoArchiveSw") then
    Sw = profile.GetItemValue("SettoArchiveSw")(0)
    else
    Exit sub
    end if

    Err=0, Error=, Line=0 говорит, что отработал без ошибок.
    В ArcResp тоже желательно написать обработчик ошибок, ошибка может быть и там. В зависимости от того, это sub или function перед меткой обработки ошибок "err1:" надо написать exit sub или exit function (не забыли это сделать в коде агента?)
     
  7. dozer

    dozer Гость

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

    А вот код для ArcResp:
    OKEN, Target - All documents in database

    Сегодня на работе жара, так что по остальным замечаниям посмотрю завтра и отпишусь.

    Заранее спасибо за помощь!
     
  8. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    Сразу Set doc = dc.GetNextDocument (doc) нельзя использовать, если документ doc как-то убивается из базы, в данном агенте этого не делается. Так что можно и сразу получать, и так, как написано в агенте - это не должно приводить к ошибке.

    Уточню по п.1
    Если Target - все документы и документы отбираются по db.UnprocessedDocuments, то условие, по которому документы отбирались изначально (Form = "Document" & Status = "X" & Archive != "1"), в общем-то, не проверяется и не нужно.
    Почему изменено определение коллекции документов для обработки при архивировании - вопрос к разработчикам СЭД, наверно, в этом был глубокий смысл =)
    В коллекцию попадают все документы в базе и поэтому никто не гарантирует наличие в них "AuthorSite" (тут может быть одна из причин ошибки).

    По п.2 Иногда серверный агент получает в обработку "пустые" документы, стабы или невалидные документы (документы, к которым нет доступа). Тогда responses может быть и Nothing, так что можно добавить еще в ArcResp указание не обрабатывать подобные документы:
    Код (Text):
    Set responses = doc.Responses
    if responses is nothing then Exit sub ' на всякий случай
    Set response = responses.GetFirstDocument
    While Not response Is Nothing
    if response.Isvalid and not response.isDeleted and not isEmpty(response.items) then ' отсекаем "битые"
    Call ArcResp (response)
    ... ' и т.д. код агента
    Call response.Save (True,True)
    end if
    Set tempdoc = responses.GetNextDocument (response)
    Delete response
    Set response = tempdoc
    Wend
    P.S. И главное чуть не забыли...
    Проверка doc.GetItemValue ("AuthorSite")(0) = s.username в серверном агенте предполагает, что в документе поле AuthorSite содержит имя сервера, поэтому на локальном компьютере агент может не выдавать ошибки, так как не сможет обработать ни одного документа!
    Если у вас локальная копия БД, можно закомментировать эту проверку (или вместо s.username написать то, что в документах должно быть в этом поле). При достаточном доступе к документам в базе можно попробовать запустить локально агент (это совет только для тестирования, вкупе с обработчиком ошибок (или даже отладчиком) для определения "битого" документа, на сервере в итоговом варианте так делать не надо!!!)
     
  9. dozer

    dozer Гость

    Я снова тут ))
    (из-за перебоев пропала одна моя тема, некоторые сообщения в этой теме и мой пароль! пришлось восстанавливать)
    Ну а теперь к делу...

    OKEN, большое спасибо! Советы помогли. На локальной базе все получилось отработать. Оказалось много битых доков, т.е. с потерянными связями. Но когда начал пробовать на живой, сразу пошли сюрпризы. Первый из них - обработчик ошибок не работает. Запускаю агент вручную, он думает-думает, потом просто выдает окошко Object variable not set, а в строке состояния пусто - ни ошибки, ни UI, ничего.
    Сейчас разница между локальной базой и рабочей только в одной строчке агента:
    Как обойти Object variable not set, я теперь знаю. Но все-таки хотелось, чтобы сообщение об ошибке выходило, т.к. в других документах есть еще кое-какие косяки, которые нужно поправить. Без них агент до конца так и не отработает.
     
  10. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Ответ от госпожи OKEN (у неё, к сожалению, в данный проблемы со входом на форум):
    "Агент должен быть подписан сервером (s.username).
    Ну, код там так написан и поле так заполняется.
    Надо переделывать на проверку сервера текущей бд, по-хорошему, но это не к тебе предложение.
    В обработчике ошибок есть проверка на Nothing документа перед выводом унида?"
     
  11. dozer

    dozer Гость

    Нет, обработка выглядит следующим образом:
     
  12. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Не, ну госпожа OKEN просто чудо, нет?
    Вот её ответ:

    1. "Запускаю агент вручную, он думает-думает" - это наверно, поиск выполняет (db.Search), который потом не использует никак. Если закомментировать его - быстрее думать начал бы. ;)

    Опять же эта дурацкая проверка на AuthorSite...
    Подобный агент подписывается сервером и на сервере запускать его лучше консольной командой (если есть соответствующие права), подставив нужное имя БД и агента.
    Выдержка из хелпа Domino Administrator) по Tell Amgr Run:
    Смотреть принты тогда надо в логе сервера.
    Если нет прав на использование консоли или лень разбираться с этим, ставить на тестовой БД расписание агента на 5-10-15 минут, подписывать сервером и ждать его запуска.

    2. За окошко "Object variable not set". Обработчик ошибок не должен содержать ошибки =)
    в исчезнувших сообщениях были примеры обработчика с проверкой документа на Nothing.
    Думаю, вам не жалко описать лишнюю переменную для обработчика ошибок, чтоб не дублировать общий код обработчика в процедуре. Сейчас приведу код только для указанного выше обработчика:
    Код (Text):
    Dim ErrText as String
    On Error Goto err1
    ...
    exitF:
    Exit Sub
    err1:
    if not doc is Nothing then
    ErrText = " при обработке документа с UI=" & doc.UniversalID
    end if
    Print "Err=" & Err & ", Error=" & Error & ", Line=" & Erl & ErrText & ", " & getthreadinfo(1)
    resume exitF
    End Sub
    Надеюсь, вы успели какую-то обработку ошибок вписать в ArcResp, проверив там свою переменную для Notesdocument на Nothing. Если нет, покатит такой вариант - меняйте doc на response и действуйте аналогично приведенному коду.
     
  13. dozer

    dozer Гость

    Да уж, такой подробной помощи я точно не ожидал! ))
    Большое спасибо...



    1. "Запускаю агент вручную, он думает-думает" - это наверно, поиск выполняет (db.Search), который потом не использует никак. Если закомментировать его - быстрее думать начал бы.

    Я уже закомментировал строчку
    Код (Text):
    Set dc = db.UnprocessedDocuments
    а вот
    Код (Text):
    search$ = {Form = "Document" & Status = "X" & Archive != "1"}
    Set db = session.CurrentDatabase
    Set dc = db.Search(search$, Nothing, 0)
    оставил, т.к. там идет выборка закрытых, но еще не заархивированных документов и она работает - теперь архивируются только закрытые документы, а не просто все старые.
    Тут поясню - это все происходит в базе согласования договоров, так что в архив идут только завершенные согласования, еще действующие не должны туда уходить, хоть они и подходят по срокам.

    Опять же эта дурацкая проверка на AuthorSite...
    Подобный агент подписывается сервером и на сервере запускать его лучше консольной командой.


    Здесь мне еще нужно повнимательней поковыряться...

    2. За окошко "Object variable not set". Обработчик ошибок не должен содержать ошибки =)
    в исчезнувших сообщениях были примеры обработчика с проверкой документа на Nothing.


    Вот с этим тоже надо еще поработать.
     
Загрузка...
Похожие Темы - Object Variable Not
  1. Cleric-Lviv
    Ответов:
    19
    Просмотров:
    5.310
  2. iosif88
    Ответов:
    11
    Просмотров:
    5.152
  3. motogarri
    Ответов:
    6
    Просмотров:
    327
  4. vsokol
    Ответов:
    0
    Просмотров:
    1.090
  5. imendan
    Ответов:
    7
    Просмотров:
    1.546

Поделиться этой страницей