Exception lost after rethrow - c#

I have a method ValidarConexaoEPI which validates a connection string trying to open a connection with it. In case of exceptions, the method who had call the "validate" one SolicitarNovaSincronizacao, catches it and rethrow a manipulated exception.
public static SincronizacaoSinc SolicitarNovaSincronizacao(int? idUsuario, int idAlmoxarifado, string versaoAplicacao, bool validaSincronizacaoEmAndatmento = true)
{
SincronizacaoSinc sincronizacaoSinc = null;
using (var conexaoLocal = new SqlConnectionEPI(_DbLocalConnectionString))
using (var conexaoServidor = new SqlConnectionEPI(_DbOnlineConnectionString))
{
sincronizacaoSinc = new SincronizacaoSinc(idUsuario, idAlmoxarifado, versaoAplicacao);
try
{
if (UtilDataAccess.ValidarConexaoEPI(conexaoLocal) && UtilDataAccess.ValidarConexaoEPI(conexaoServidor))
{
ValidarAlmoxarifadoBaseOnline(conexaoServidor, idAlmoxarifado);
ValidarUsuarioBaseOnline(conexaoServidor, idUsuario);
CriarRegistroSincronizacao(conexaoLocal, conexaoServidor, sincronizacaoSinc);
if(validaSincronizacaoEmAndatmento)
{
SolicitarSincronizacao(conexaoServidor, sincronizacaoSinc);
}
AtualizarRegistroSincronizacao(conexaoLocal, conexaoServidor, sincronizacaoSinc);
}
conexaoServidor.SqlTransaction.Commit();
conexaoLocal.SqlTransaction.Commit();
}
catch (Exception exception)
{
throw new Exception(String.Format(
"Erro ao iniciar sincronizacao. {0}", exception.Message), exception.InnerException);
}
}
return sincronizacaoSinc;
}
public static bool ValidarConexaoEPI(SqlConnectionEPI conexao) //This method is in another static class
{
try
{
conexao.Open();
}
catch (SqlException sqlException)
{
var dataSource = conexao != null && conexao.SqlConnection != null
? conexao.SqlConnection.DataSource : "string de conexão inválida";
throw new Exception(String.Format(
"Não foi possível estabelecer uma conexão com o banco de dados ({0}).", dataSource), sqlException);
}
catch (Exception exception)
{
throw new Exception(String.Format(
"Não foi possível estabelecer uma conexão com o banco de dados: {0}", exception.Message), exception);
}
return true;
}
But, after rethrow I lost the exception data. The next method, the one who called the SolicitarNovaSincronizacao() receive a NullReference exception. As you can see:
Exception catch on ValidarConexaoEPI():
NullReference exception catch:
Every other exception catch by SolicitarNovaSincronizacao is ok, the problem occur just with this one. The exception used to mount the new one is ok.
PS.: I know that it is not the right use of try/catch! Not my code.
EDIT:
Here is the StackTrace of the NullReferenceException:
em AG.ControleEPI.Dados.SqlConnectionEPI.Dispose() na C:\Projetos\AG\TFS2013\ControleEPI\Main\Source-locais\AG.ControleEPI.Dados\ADO\SqlConnectionEPI.cs:linha 28
em AG.ControleEPI.Dados.ADO.SincronizacaoDataAccess.SolicitarNovaSincronizacao(Nullable`1 idUsuario, Int32 idAlmoxarifado, String versaoAplicacao, Boolean validaSincronizacaoEmAndatmento) na C:\Projetos\AG\TFS2013\ControleEPI\Main\Source-locais\AG.ControleEPI.Dados\ADO\SincronizacaoOnline\SincronizacaoDataAccess.cs:linha 50
em AG.ControleEPI.Negocio.Gerenciador.SincronizacaoGerenciador.IniciarSincronizacao(Int32 idUsuario, Int32 idAlmoxarifado, String versaoAplicacao) na C:\Projetos\AG\TFS2013\ControleEPI\Main\Source-locais\AG.ControleEPI.Negocio\GerenciadorCustomizado\SincronizacaoGerenciador.cs:linha 84

Related

Azure Servicebus Topic continuos Receiver message stops

I builded a Azure Service Bus Message provider to run in linux CENTOS 7 with core 2.0. I'm using the packge "Microsoft.Azure.ServiceBus 3.1.0". But when I receive
five hundred thousand(500 000) or more messages, the "RegisterMessageHandler" stop even with many active messages to read, does't receive anymore. I have five threads, "MaxConcurrentCall" with one hundred, Prefechcount 100 and "MaxAutoRenewDuration" in five minutes.
This method use "RegisterMessageHandler" to keep reading subscription continuously.
public async Task RecebeMensagemAsync(CancellationToken cancellationToken, Action<string> tratarObjetoImportado, int prefetchCount)
{
try
{
var receiver = new Microsoft.Azure.ServiceBus.SubscriptionClient(_serviceBusConnString, _topic, _subscription, this._receiveMode, new RetryExponential(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), _retryPolicyMaximumRetryCount));
receiver.PrefetchCount = prefetchCount;
receiver.OperationTimeout = TimeSpan.FromMinutes(_timoutOperacao);
var cicloRecebimentoCompleto = new TaskCompletionSource<bool>();
// fecha receiver e factory quando o CancellationToken é acionado
cancellationToken.Register(
async () =>
{
await receiver.CloseAsync();
cicloRecebimentoCompleto.SetResult(true);
});
// registra o RegisterMessageHandler para tratar mensagem lida assincronamente
receiver.RegisterMessageHandler(
async (message, cancellationTokenResponse) =>
{
if (message.Body == null || message.Body.Length == 0)
{
GerenciadorLog.LogInfo($"Mensagem não possui conteudo, mensageId: {message.MessageId}", LogType.Warning);
await receiver.CompleteAsync(message.SystemProperties.LockToken);
}
else
{
try
{
tratarObjetoImportado(Encoding.UTF8.GetString(message.Body));
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.CompleteAsync(message.SystemProperties.LockToken);
}
catch (MessageSizeExceededException ex) {
GerenciadorLog.LogError($"Tamanho da mensagem:{message.MessageId}", ex);
try
{
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.DeadLetterAsync(message.SystemProperties.LockToken);
}
catch (Exception dlex)
{
GerenciadorLog.LogError($"Erro ao enviar mensagem para 'DeadLetter', mensageId: {message.MessageId}", dlex);
throw new Exception("Erro não identificado", dlex);
}
}
catch (MessageLockLostException ex)
{
GerenciadorLog.LogError($"Expirou tempo de leitura da mensagem, será enviada para DeadLetter:{message.MessageId}", ex);
try
{
await receiver.AbandonAsync(message.SystemProperties.LockToken);
}
catch (Exception ex2)
{
GerenciadorLog.LogError($"Erro ao abandonar mensagem, mensageId:{message.MessageId}", ex2);
await Task.CompletedTask;
}
}
catch (MessagingEntityNotFoundException ex)
{
GerenciadorLog.LogError($"Mensagem não encontrada, mensageId:{message.MessageId}", ex);
try
{
await receiver.AbandonAsync(message.SystemProperties.LockToken);
}
catch (Exception ex2)
{
GerenciadorLog.LogError($"Erro ao abandonar mensagem, mensageId:{message.MessageId}", ex2);
await Task.CompletedTask;
}
}
catch (Exception ex)
{
if (ex != null && !string.IsNullOrEmpty(ex.Message))
GerenciadorLog.LogError($"Erro na importação, mensageId:{message.MessageId}", ex);
try
{
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.DeadLetterAsync(message.SystemProperties.LockToken);
}
catch (Exception dlex)
{
GerenciadorLog.LogError($"Erro ao enviar mensagem para 'DeadLetter', mensageId: {message.MessageId}", dlex);
await Task.CompletedTask;
}
}
}
},
new MessageHandlerOptions((e) => LogMessageHandlerException(e, receiver)) { AutoComplete = false, MaxConcurrentCalls = _maxConcurrentCalls, MaxAutoRenewDuration = TimeSpan.FromSeconds(_lockDuration) });
await cicloRecebimentoCompleto.Task;
}
catch (Exception ex)
{
GerenciadorLog.LogError("Erro ao configurar 'listener' para leitura das mensagens.");
GerenciadorLog.LogError(ex.Message, ex);
throw ex;
}
}
And this method keep await the task. Can have more than one thread calling this method
public async Task Run(int segundosIntnervaloSondaConsultaTopico, int prefetchCount, Action<string> tratarObjetoImportado)
{
IList<CancellationTokenSource> cancellationTokensSource = new List<CancellationTokenSource>();
IList<Task> instanciasDasSondas = new List<Task>();
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
GerenciadorLog.LogInfo($"start blablalbala --");
var recebeMensagemAsync = RecebeMensagemAsync(cancellationTokenSource.Token, tratarObjetoImportado, prefetchCount);
await Task.WhenAll(Task.Run(() => Console.ReadKey()),
Task.Delay(TimeSpan.FromSeconds(segundosIntnervaloSondaConsultaTopico)).ContinueWith((t) => cancellationTokenSource),
Task.WhenAll(new Task[] { recebeMensagemAsync }));
}
Somebody knows the correct way to keep running or renew the client of register, or another approach?
It was fixed after update to "Microsoft.Azure.ServiceBus 3.1.1" package:
https://www.nuget.org/packages/Microsoft.Azure.ServiceBus/
tks.

Xamarin httpclient does not run more than once

I am using httpclient to get data from an Api Rest through Xamarin. My problem happens when I'm going to run httpclient again on a new page to get back the api information, that is, this works only once, how do I solve it?
Code:
private async void ObterNoticiasXbox()
{
var respXbox = string.Empty;
try
{
var uriXbox = new HttpClient()
{
BaseAddress = new Uri("http://api.newsplay.com.br")
};
var urlXbox = "/post/";
var resultXbox = await uriXbox.GetAsync(urlXbox);
if (!resultXbox.IsSuccessStatusCode)
{
await DisplayAlert("Erro de Conexão", "Não foi possível obter as notícias do servidor, Tente novamente mais tarde!", "OK");
return;
}
respXbox = await resultXbox.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
await DisplayAlert("Erro de Conexão com o Servidor", ex.Message, "OK");
return;
}
// transformando o retorno em objeto através do json e deserealize e retornando em lista
var NXbox = JsonConvert.DeserializeObject<List<XboxModels>>(respXbox);
//Adicionando os itens ao ListView na Home.xaml
XboxList.ItemsSource = NXbox;
}
}

Owin Self Host Will Not Start

using VS2015 with admin permissions my host starts and I can receive requests using Nancyfx.
IDisposable host = null;
IDisposable HostStart()
{
try
{
return WebApp.Start<Startup1>("http://*:7002");
}
catch (HttpListenerException ex)
{
throw new Exception(ex.Message);
}
}
When I make a setup project with the Visual Studio Extension and build and install and then run with admin privalages I don't get any exceptions but the server can not be found.I have turned off the firewall.I have now run out of ideas?
UPDATE: I am getting an exception
An exception has been thrown by the taget of invocation.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Object reference not set to an instance of an object.
at CabbyTechOffice.Startup1.Configuration(IAppBuilder app)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Owin.Loader.DefaultLoader.<>c__DisplayClass12. <MakeDelegate>b__b(IAppBuilder builder)
at Owin.Loader.DefaultLoader.<>c__DisplayClass1. <LoadImplementation>b__0(IAppBuilder builder)
at Microsoft.Owin.Hosting.Engine.HostingEngine.ResolveApp(StartContext context)
at Microsoft.Owin.Hosting.Engine.HostingEngine.Start(StartContext context)
at Microsoft.Owin.Hosting.Starter.DirectHostingStarter.Start(StartOptions options)
at Microsoft.Owin.Hosting.Starter.HostingStarter.Start(StartOptions options)
at Microsoft.Owin.Hosting.WebApp.StartImplementation(IServiceProvider services, StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start(StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start[TStartup](StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start[TStartup](String url)
at CabbyTechOffice.MAIN.HostStart()
It seems the null ref is in the startup:
public class MyBoot : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
CabbyTechOfficeConfig fig = ConfigUI.GetCabbyTechConfig();
if (fig == null)
{
throw new Exception("NO CONFIG");
}
ICabbytechOfficeDataAccess DB = null;
try
{
DB = ConnDBCreater.CreateDB(fig.DatabaseComputerName + "\\" + fig.DatabaseInstanceName, "taxidb", fig.DbPassword, 8);
IPEndPoint smsEP = null;
SmsCommsMob sms = null;
var comms = new ControlConnectAndSend(new IPEndPoint(IPAddress.Any, fig.DispatchFromPDAServerPort));
try
{
smsEP = new IPEndPoint(IPAddress.Parse(fig.SmsIp), fig.SmsPort);
sms = new SmsCommsMob(smsEP);
}
catch (Exception)
{
}
StateInjector stateInjector = new StateInjector(DB, comms, sms);
UdpBroadcasterJson.Send(new UDPCmd() { code = UDPCmd.commandsEnum.broadcastForDispatch }, stateInjector.UDPDispatchPort);
try
{
var comp = DB.CompaniesGet();
stateInjector.CompanyName = comp.company;
}
catch (Exception)
{
}
try
{
stateInjector.zones = DB.ZonesGet();
}
catch (Exception)
{
}
try
{
var locLog = new PdaLocLog();
var locLogger = new PdaLocLogger(DB, locLog);
stateInjector.locLogger = locLogger;
}
catch (Exception)
{
}
container.Register<IStateInjector, StateInjector>(stateInjector);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
You have chains of try/catches with empty catch blocks.
try
{
var comp = DB.CompaniesGet();
stateInjector.CompanyName = comp.company;
}
catch (Exception)
{
}
try
{
stateInjector.zones = DB.ZonesGet();
}
catch (Exception)
{
}
try
{
var locLog = new PdaLocLog();
var locLogger = new PdaLocLogger(DB, locLog);
stateInjector.locLogger = locLogger;
}
catch (Exception)
{
}
this could leave stateInjector null which you then try to use.
You need to handle the catches in such a way that you can log any problems in those try/catches. Presumably there's a problem in the environment where it's failing, but you don't know that because of the empty catches.
There was problem in TinyIoc container in the NancyFx bootstrapper due to bad design in the exception handlers and a dependency was being injected null.

Generic connection bulder

I've to create an embedded monitoring for existing application, these applications are using both Entity Framework and ADO. I have to check if the connections strings are good, and I'm doing it this way actually:
if (c.ConnectionString.Contains("metadata"))
{
using (var connection = new EntityConnection(c.ConnectionString))
{
try
{
connection.Open();
isWorking = true;
connection.Close();
}
catch (EntityException)
{
// Le catch n'a pas de raison d'être, la variable étant à false par défaut
}
}
}
else
{
using (var connection = new SqlConnection(c.ConnectionString))
{
try
{
connection.Open();
isWorking = true;
connection.Close();
}
catch (SqlException)
{
// Le catch n'a pas de raison d'être, la variable étant à false par défaut
}
}
}
But I've a lot of redundancy. How can I develop this thing to only got the try catch one time and not one for Entity an one for SQL ?
The connections strings are actually retrieved with System.Configuration.ConfigurationManager.ConnectionStrings
Thank you.
EntityConnection and SqlConnection both inherit from DbConnection as their common ancestor, so you can write a function that simply takes an instance of DbConnection and leave the rest of your code pretty much the same.
public bool CheckConnection(DbConnection connection)
{
try
{
connection.Open();
connection.Close();
return true;
}
catch (Exception)
{
// Le catch n'a pas de raison d'être, la variable étant à false par défaut.
}
return false;
}
You can then call your code using the same logic:
if (c.ConnectionString.Contains("metadata"))
{
using (var connection = new EntityConnection(c.ConnectionString))
{
isWorking = CheckConnection(connection);
}
}
else
{
using (var connection = new SqlConnection(c.ConnectionString))
{
isWorking = CheckConnection(connection);
}
}
This is just a simple refactoring using what you already have without changing the logic of your code.
If you don't want to catch the generic exception (which in my opinion is completely fine in this case), C# 6 offers a new construct to allow catching certain exceptions more generically:
catch (Exception ex) when (ex is EntityException || ex is SqlException)
{
// exception handling code
}
Also, if there is no additional logic in your if ... else statement, you can use a single using block:
if (c.ConnectionString.Contains("metadata"))
{
connection = new EntityConnection(c.ConnectionString);
}
else
{
connection = new SqlConnection(c.ConnectionString);
}
using (connection)
{
// same as before.
}
The next logical step would then be to make some sort of factory class / method that extracts and creates your different connections.
Since both are derived from DbConnection, you could do this:
using(DbConnection connection = c.ConnectionString.Contains("metadata") ?
new EntityConnection(c.ConnectionString) as DbConnection: new SqlConnection(c.ConnectionString) as DbConnection)
{
try
{
connection.Open();
isWorking = true;
connection.Close();
}
catch (Exception e) //make this more generic
{
//Do something
}
}
By making use of DbConnection (instead of individual Connection), you could test your connection.

null data time value

Hi Im trying to save a null value for a datetime (fechaNac) but i cant do it .is it possible to do it using my generic code in asp?
public int add(Cliente dato)
{
string cmdText = "insert into clientes values ( #nombre, #apellido,#telefono,#celular,#oldtelefono, #oldcelular, #dni , #fechaNac)";
Dictionary<string, Object> parametros = new Dictionary<string, Object>();
parametros.Add("#nombre", dato.Nombre);
parametros.Add("#apellido", dato.Apellido);
parametros.Add("#telefono", dato.Telefono);
parametros.Add("#celular", dato.Celular);
parametros.Add("#oldtelefono", dato.OldTelefono);
parametros.Add("#oldcelular", dato.OldCelular);
parametros.Add("#dni", dato.Dni);
parametros.Add("#fechaNac", dato.FechaNac);
try
{
return this.setData(cmdText, parametros);
}
catch (Exception ex)
{
throw new Exception("No se pudo insertar el usuario en la base de datos", ex);
}
}
public int setData(string cmdText, Dictionary<string, Object> listaParametros)
{
int res;
using (SqlCommand cmd = new SqlCommand(cmdText, cn)) {
foreach (KeyValuePair<string, Object> parametro in listaParametros) {
cmd.Parameters.AddWithValue(parametro.Key, parametro.Value);
}
Conectar();
try {
res = cmd.ExecuteNonQuery();
} catch (Exception ex) {
throw new Exception("No se pudo insertar el dato", ex);
} finally {
Desconectar();
}
}
return res;
}
thanks in advance for your help!
Yanina
Yes, but you need to coalesce it to DBNull.Value first.
cmd.Parameters.AddWithValue(parametro.Key, parametro.Value ?? DBNull.Value);

Categories

Resources