Тотальная неудачница и убийца жёстких дисков.
#post-id: 4619-01-55
#original-date: 19.03.2013 Tue
#original-time: 1:55 AM
#original-day:  4619
#original-host: WinXP Home SP3 (Build 2600)

Пофиксила давнюю неприятность в классах ajpSendMail и ajpSendMail2.

Там используется объект CDO.Message, который облегчет отправку почты, позволяя сильно настроить письмо не создавая его ручками. Даже доставку объект берёт на себя. Но поскольку объект имеет несколько инопланетный интерфейс, я написала обёртку, которая позволяла одним вызовом сделать всё, что нужно. Позже я написала другую версию класса, где параметры перешли в свойства и появилась возможность получать исходник письма.

Так вот, проблема была в том, что описания ошибки возвращались с крякозябрами, как при неправильной перекодировке windows-1251 в windows-1252. Я было вытащила старый код, который перегоняет всё обратно беря за основу UNICODE символы, но оказалось, что все эти "???aooon???aaa" - это уже ANSI, так что восстановить нельзя. В итоге пришлось терпеть нечитаемые сообщения об ошибках.

Но сегодня я вдруг наткнулась на список кодов и описание ошибок по-английски.

http://fredshen.wordpress.com/2009/08/14/cdo-message-error/

Быстро смекнув, я написала функцию, которая детектит крякозябы (по вопросительным знакам) и по коду подставляет новое описание. При чём пришлось передавать ошибку как-то так. Объявила структуру, похожую на объект Err:



Потом вызвала функцию отправки вот так:



Тоесть у нас ошибка глушится при вызове Send(). Раньше она свободно уходила наверх. Потом члены объекта Err перекидываются в структуру, а структура уже уходит в специальную функцию. Структура нужна чтобы объект Err ненароком не сбросился. Функция же выполняется уже без обработчика ошибок.

В функции проверяется код ошибки, содержимое текста. текст фиксится, если надо, а потом делается это:



Таким образом, ошибка генерируется снова, но с поправленным текстом.

Но я не остановилась на этом. Хотелось понять, есть ли возможность заставить объект возвращать сообщение на английском. Ведь некоторые ошибки имели символы подстановки для неких значений.

Оказалось, что можно. Достаточно вызвать SetThreadLocale() и указать английский язык. И это только на время выполнения Send(). Таким образом я сделала небольшой класс чтобы это дело компактно упорядочить. Вот такой вот:



Ну и вызов идёт так:



Чтобы ничего не запороть, локаль меняется только когда изначально она - русская. В итоге объект уверен, что выполняется в американской Windows и возвращает сообщение на английском языке. Но фиксер всё равно оставила, для страховки и приведения сообщения в божеский вид - там были непонятные точки и переносы.

Но всёже одна проблема осталась. Это ошибки такого вида:

The message could not be sent to the SMTP server. The transport error code was 0x80040217. The server response was not available

Ошибка с указанным в сообщении кодом выглядит так:

The transport was unable to log on to the server

Тоесть пароль был неправильный.

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

#upd: Разница налицо. Before:

[20.03.2013] [10:20:01 AM] Hard times. Using E-Mail publishing method to upload picture.
[20.03.2013] [10:20:37 AM] Can't mail picture! Details are below.
[20.03.2013] [10:20:37 AM] ajpSendMail2 error 2'147'746'323 (0x80040213): O?ainii?oo ia oaaeinu iiaee??eouny e na?aa?o.


After:

[20.03.2013] [12:20:00 PM] Hard times. Using E-Mail publishing method to upload picture.
[20.03.2013] [12:22:39 PM] Can't mail picture! Details are below.
[20.03.2013] [12:22:39 PM] ajpSendMail2 error 2'147'746'322 (0x80040212): The transport lost its connection to the server


Кстати, ошибка разная OO Хотя оно понятно, на работе инет более-менее, поэтому там сразу ошибка коннекта, а "дома" (второй случай) произошёл таймаут или вроде того, потому что скорость низкая в последнее время.