PDA

Ver la Versión Completa : como capturar una excepcion al enviar mail smtp indy gmail


kapcomx
29-06-2012, 00:00:12
Que tal Compañeros, Un saludo a todos los que forman parte de este gran Foro, Pues nuevamente acudo a ustedes con un problema, pues resulta que donde trabajo tenia un programa que enviaba archivos de pedido a los clientes usaba idsmtp y idmessage y funcionaba todo muy bien lo tenia configurado para que se enviara de un servidor muy especifico de la empresa, pero me pidieron que lo cmabiara para que se pudiera enviar desde cualquier cuenta de gmail.

buscando en el Foro encontre un excelente ejemplo de el compañero Roman, el cual me funciona muy bien, el único detalle que tengo es que si al momento de enviar el correo me pide una contraseña, si la escribo correctamente no hay problema, pero si es erronea me salta un mensaje de error (el cual si estuviera en español seria perfecto).

project my_proyecto raised exception class EidSMTPReply error with message 'Username and password not accepted' . learn more at

y me da una liga de ayuda de gmail.

me gustaria saber como cachar esa excepcion para en lugar de ese mensaje pudiera poner uno propio.
lo he intentado asi pero no me funciona como quiero por que primero sale el mensaje mencionado y luego el mio.

procedure Tfrmenviaproveedor2.btnEnviarCorreoClick(Sender: TObject);
var
Password: String;
filename: String;
begin
filename:= ed_archivo.Text;
idMessage.Clear;
idMessage.FromList.EMailAddresses := 'lacuentadegmail@gmail.com';
idMessage.Recipients.EMailAddresses := ed_mail.Text;
idMessage.Subject := 'Confirmar Existencias';
idMessage.AttachmentTempDirectory := filename;
TIdAttachmentfile.create(idMessage.MessageParts,filename);
mmobserva.Lines.Add('Mensaje de Correo enviado desde Sistema Informatico XXXXXXX.');
idMessage.Body.AddStrings(mmobserva.Lines);
if InputQuery('Comercializadora XXXXXX', 'Contraseña del servidor', Password) then
begin
idSMTP.Username := 'lacuentadegmail@gmail.com';
idSMTP.Password := Password;
btnEnviarCorreo.Enabled := false;
try
if not idSMTP.Connected then
idSMTP.Connect;
idSMTP.Send(IdMessage);
except
showmessage('Ocurrio un error al Intentar enviar el Correo, Verifique el password indicado');
rebote:=true;
btnEnviarCorreo.Enabled := true;
end;
end;
end;


De antemano les agradezco a quienes puedan ayudarme

Saludos...:cool:

Casimiro Notevi
29-06-2012, 00:18:36
lo he intentado asi pero no me funciona como quiero por que primero sale el mensaje mencionado y luego el mio.

Eso será si lo ejecutas desde delphi, porque si lo haces desde fuera entonces sólo saldrá tu mensaje :)

kapcomx
29-06-2012, 16:27:55
Mi buen Casimiro, eres un Genio...
Ya me habia pasado algo así una vez. jejejejeje que cosas....
a veces haces lo más dificil y te atoras en lo mas facil....

Saludos...:cool:

P.D. Para la proxima prometo agotar esa posibilidad antes de preguntar jejejeje....

Casimiro Notevi
29-06-2012, 16:37:50
Mi buen Casimiro, eres un Genio...

Qué más quisiera yo, me pediría 3 deseos :D

martini002
04-08-2013, 04:04:51
Hola muchachos, vine a revivir este fantasma, esto mismo me pasa a mi,
y eso mismo que el amigo kapcomx queria hacer tambien me gustaria hacerlo,
capturar la excepcion y en vez que salga ese error en ingles, aparezca algo que yo coloque

ejemplo mi codigo de envio:


procedure TPantallaPrincipal.EnviarMensaje(host:string;nombre:string;password:string;port:integer;desde:string ;hasta:string;asunto:string;cuerpo:string;adjunto:string);
Var
Adjuntar:TIdAttachmentFile;
begin
Adjuntar:= nil;
IdMessage1.Clear;
idMessage1.FromList.EMailAddresses := Desde;
idMessage1.Recipients.EMailAddresses := Hasta;
idMessage1.Subject := Asunto;
idMessage1.Body.Add(Cuerpo);
idSMTP1.Username := Nombre;
idSMTP1.Password := Password;
if Adjunto <> '' then
begin
if FileExists(Adjunto) then
Adjuntar:=TIdAttachmentFile.Create(idMessage1.MessageParts, Adjunto);
Adjuntar.DisplayName := Adjunto;
Adjuntar.FileName := Adjunto;
end;
if idSMTP1.Connected then
begin
idSMTP1.Disconnect;
idSMTP1.Connect;
end
else
begin
idSMTP1.Connect;
end;

try
idSMTP1.Send(IdMessage1);
ShowMessage('Mensaje enviado exitosamente!');
except
ShowMessage('Error al enviar mensaje!');//Esto nunca se muestra
end;

if Assigned(Adjuntar) then
begin
Adjuntar.Free;
Adjuntar:= nil;
end;
ENd;



Mas especificamente aqui:


try
idSMTP1.Send(IdMessage1);
ShowMessage('Mensaje enviado exitosamente!');
except
ShowMessage('Error al enviar mensaje!');//Esto nunca se muestra cuando salta la excepcion de timeout por ejemplo
end;


que creen que pueda ser?
Saludos

Casimiro Notevi
04-08-2013, 10:31:05
Hola martini002, este tema no tiene nada que ver con el tratado en este hilo.
De todas formas, no has explicado realmente el problema que tienes :confused:

O sea, cuando envía el email te sale el mensaje "mensaje enviado exitosamente" y cuando salte una exception saldrá "error al enviar el mensaje".

El problema es que tienes que tratarlo de otra forma, idSMTP1.Send(idmessage1) debe devolver un valor que indica si ha sido enviado el mensaje o si ha habido algún error. Es ese valor el que debes tratar.
Ya que tal y como lo tienes ahora mismo, el mensaje se envía (mejor dicho, se ejecuta idsmtp.send sin error) y nunca saltará la exception. Incluso aunque no se haya podido enviar el mensaje.

martini002
05-08-2013, 10:30:46
Hola Casimiro,

Entiendo lo que dices, la cuestion es que no se como hacer para que devuelva un valor el idSMTP1.Send(IdMessage1);
El correo se envia exitosamente, solo que cuando no hay conexion salta la excepcion de timeout
no quiero que salte esa excepcion sino que siga intentando hasta que se conecte, o por lo menos hasta un numero determinado
de intentos, probe colocar algo mas en el except pero realmente desconozco mucho el uso correcto del try
y por mas que he leido no he comprendido exactamente.



try
idSMTP1.Send(IdMessage1);
ShowMessage('Mensaje enviado exitosamente!');
except
on E: Exception do
ShowMessage('Error al enviar mensaje!');//Esto nunca se muestra cuando salta la excepcion de timeout por ejemplo
end;

Casimiro Notevi
05-08-2013, 11:06:41
Ahora no tengo un delphi a mano, pero haz una búsqueda por los foros, encontrarás código que puede servirte, ejemplo:
http://www.clubdelphi.com/foros/showthread.php?t=43231&highlight=idSMTP1.Send

martini002
05-08-2013, 11:55:31
Gracias amigo Casimiro, pero con el envio de email va bien todo,
la cuestion es capturar la excepcion, eso es lo que intento hacer
por eso respondi a este hilo :)

Casimiro Notevi
05-08-2013, 12:08:39
Pero si el envio va bien entonces no salta ninguna excepción.

martini002
06-08-2013, 00:08:43
Salta la excepcion cuando no hay conexion,
y eso es lo que me gustaria capturar
para ejecutar un par de acciones

Casimiro Notevi
06-08-2013, 10:15:20
Entonces, si salta la excepción, ¿cuál es el problema?

martini002
07-08-2013, 00:31:17
LOL, no me entiendes


try
idSMTP1.Send(IdMessage1);
ShowMessage('Mensaje enviado exitosamente!');

//hasta aqui perfecto, pero cuando no exista conexion a internet
//saltara la excepcion, entonces quiero que siga intentando hasta que halla conexion a internet
//y entonces pueda enviar el correo
//pero no quiero que cuando no exista conexion a internet salte un mensaje
//porque estas son tareas de mantenimiento y no deber interrumpir la interfaz

except
on E: Exception do

//la cuestion es que cuando salta la excepcion no toca esta linea,
//por eso escribo aqui, a ver como saben ustedes capturar esto :/

ShowMessage('Error al enviar mensaje!');//Esto nunca se muestra cuando salta la excepcion de timeout por ejemplo
end;

movorack
07-08-2013, 05:01:38
Hola,

Podrías hacer una función que se encargue de enviar el correo y manejar la excepción y cada vez que falle reintentar el envío.

algo así:

const
MaxIntentos = 5;

..

function EnviarCorreo(var CanIntentos : Byte) : Boolean;
begin
try
//Codigo para envio
result := true;
except
if CanIntentos < MaxIntentos then
result := false
else
raise exception.create('Mensaje de error');
end;
end;

..

//y dentro de tu función de envío cambiar el simple send por algo asi...

procedure TuFuncionDeCorreo;
var
CanIntentos : Byte;
begin

..

CanIntentos := 0;
while not EnviarCorreo(CanIntentos) do
Inc(CanIntentos);

..

end;

martini002
07-08-2013, 12:22:25
Gracias Movorack,

me parece una solución buena,
dejame intentar hacer algo con eso y te cuento
como me va.

Saludos