I have a problem regarding try catch when creating an object in C#.
My problem appears when an object is supposed to be created and the webservice which defines the object isn't available or has been modified.
That is the problem I would like my program to handle.
When I try to do this:
try
{
var Customer = new Customer();
}
catch
{
//handling the exception.
}
Later on in my program I need that particular object, but due to the try catch the object isn't available in all cases (of course when the try fails, the object isn't created).
without if(customer != null)
if (insertCustomer(lead, LS_TS, out Customer) == true)
{
insert = true;
}
with if(customer != null)
if(customer != null)
{
if (insertCustomer(lead, LS_TS, out Customer) == true)
{
insert = true;
}
}
No matter what, the compiler says: "The name 'Customer' does not exist in the current context
How do I solve this problem? I need a program to be running all the time and when checking an object which isn't created then I need to exit the method and try again later.
Thanks in advance
You can just do this:
Customer customer = null;
try
{
customer = new Customer();
}
catch
{
// handling the exception.
}
and whenever you need to use the object customer you should do this
if(customer != null)
{
// do stuff
}
Related
I need some advice on how to deal with null objects being returned and crashing my program.
Here is my code:
var employee = _repo.GetEmployeeById(Id); //gets employee by id in ssms
if (employee != null)
{
//do something if an employee exists
return employee;
}
return null; //else return nothing
and then:
try
{
model = await employeeService.GetEmployeeById(Id);
}
catch(NullReferenceException ex)
{
//Do something about it...
}
when an ID which does not exist in the database that gets passed in, the model is null but I handle it in my try and catch a null reference exception but the program still crashes, is there any other way to handle this sort of general error?
You should first understand what a NullReferenceException is: what is a NullReferenceException and how do I fix it
If you don't know the generated exception and want your program to catch the error you should use a default exception first :
catch(Exception ex)
When you know which exception is generated then you can add a specialized catch block your code should look like this :
try{
//Your code
}
catch(YourException yEx){//Do something}
catch(Exception ex){//Do something}
I would like to use the same dbContext to save a collection of Program type objects, but if there is any exception or concurrency exception in any of the program object, I would like to rollback the whole saved collection, and need to notify user about all program objects where concurrency issue occurred. I am using Entity Framework 6.1.
Find the code snippet. I am facing an issue that, if any of program object is having concurrency exception then programContext object is throwing the same exception again even if next record is not having any concurrency issue. Please guide on this if it is wrong then how can we achieve it in EF6.1
//Code
public List<ProgramViewModel> SavePrograms(List<ProgramViewModel> newAndUpdatedPrograms)
{
List<ProgramViewModel> failedPrograms = new List<ProgramViewModel>();
using (ProgramContext programContext = new ProgramContext())
{
using (DbContextTransaction dbProgramTransaction = programContext.Database.BeginTransaction())
{
bool isErrorOccured = false;
foreach (var item in newAndUpdatedPrograms)
{
try
{
Program program = new Program();
program.ProgramID = item.ProgramId;
program.Title = item.Title;
program.ProgramCode = item.ProgramCode;
program.Description = item.Description;
//This is to check whether user is having the latest record or dirty record (Concurency check)
program.RowVersion = System.Convert.FromBase64String(item.RowVersion);
if (program.ProgramID == 0)
programContext.Entry(program).State = System.Data.Entity.EntityState.Added;
else
programContext.Entry(program).State = System.Data.Entity.EntityState.Modified;
programContext.SaveChanges(); //Throws the previous concurrency exception here
}
catch (DbUpdateConcurrencyException ex)
{
isErrorOccured = true;
failedPrograms.Add(item);
}
}
if (isErrorOccured)
{
dbProgramTransaction.Rollback();
}
else
{
dbProgramTransaction.Commit();
}
}
}
return failedPrograms;
}
I am trying to handle a NullReference Exception, but i am confused how to handle that. Here is my sample code where a NullReference exception is raised:
private Customer GetCustomer(string unformatedTaxId)
{
return loan.GetCustomerByTaxId(new TaxId(unformatedTaxId));
}
Now i am handling this in the following method
public void ProcessApplicantAddress(ApplicantAddress line)
{
try
{
Customer customer = GetCustomer(line.TaxId);
//if (customer == null)
//{
// eventListener.HandleEvent(Severity.Informational, line.GetType().Name, String.Format("Could not find the customer corresponding to the taxId '{0}' Applicant address will not be imported.", new TaxId(line.TaxId).Masked));
// return;
//}
Address address = new Address();
address.AddressLine1 = line.StreetAddress;
address.City = line.City;
address.State = State.TryFindById<State>(line.State);
address.Zip = ZipPlusFour(line.Zip, line.ZipCodePlusFour);
}
catch(NullReferenceException e)
{
//eventListener.HandleEvent(Severity.Informational, line.GetType().Name, String.Format("Could not find the customer corresponding to the taxId '{0}' Applicant address will not be imported.", new TaxId(line.TaxId).Masked));
eventListener.HandleEvent(Severity.Informational, line.GetType().Name, e.Message);
}
}
I the previous case i am writing like if(customer == null) now i should get rid of that code so that i can handle it in the catch block.
Please help me how to throw that exception.
I am trying to handle a NullReference Exception, but i am confused how
to handle that
Well you already have by checking if customer is null. You need that check in place.
Throwing an exception is expensive, and knowing that this exception can be caused if the TaxId is not valid is not really an exceptional case, it's a problem in validating the user input in my opinion.
If an object can return null, simply check that object's value before trying to access the properties/methods. I would never allow an exception to be thrown and interrupt the standard program flow just to catch an Exception and log it.
I'd do something like
public void ProcessApplicantAddress(ApplicantAddress line)
{
if (line == null)
{
eventListener.HandleEvent(Severity.Informational, line.GetType().Name, "a message");
throw new ArgumentNullException("line");
}
Customer customer = GetCustomer(line.TaxId);
if (customer == null)
{
eventListener.HandleEvent(Severity.Informational, line.GetType().Name, "a message");
throw new InvalidOperationException("a message");
}
Address address = new Address();
if (address == null)
{
eventListener.HandleEvent(Severity.Informational, line.GetType().Name, "a message");
throw new InvalidOperationException("a message");
}
address.AddressLine1 = line.StreetAddress;
address.City = line.City;
address.State = State.TryFindById<State>(line.State);
address.Zip = ZipPlusFour(line.Zip, line.ZipCodePlusFour);
}
The caller is responsable to handle exceptions and to validate args that sends.
I am making a save option in my program that saves the changes to a file. I am using this code to save and get a MessageBox to show the result of the process I am getting an error on this line "Object reference not set to an instance of an object."
SaveFileCheck = StockHandler.SaveChangesToFile();
this is my code
private void Save_Click(object sender, EventArgs e)
{
bool SaveFileCheck = false;
var result = MessageBox.Show("Are you sure you want to Save the changes ?", "My Application",
MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
if (result == DialogResult.Yes)
{
SaveFileCheck = StockHandler.SaveChangesToFile();
if (SaveFileCheck)
{
MessageBox.Show("The process was a success");
}
else
{
MessageBox.Show("The process failed please make sure that the file is not been used and try again");
}
//Save the file back
}
}
}
}
public bool SaveChangesToFile()
{
try
{
if (FileName != null)
{
using (StreamWriter Write = new StreamWriter(FileName, false))
{
foreach (Stock s in FileStockList)
{
Write.Write(s.ToString() + "\r\n");
}
}
}
else {
return false;
}
}
catch(IOException ex)
{
return false;
throw new ArgumentException("something went wrong an error" + ex + "is been cought");
}
return true;
}
StockHandler is null.
If StockHandler is not a static class, you need to create an instance of it before you can call methods on it:
var handler = new StockHandler();
SaveFileCheck = handler.SaveChangesToFile();
Or, if StockHandler is a member variable:
StockHandler = new // something
You haven't shown what StockHandler is, or where you're getting it from - but it looks like it's null. You'll need it to be a reference to a valid object. There's not a lot more we can say just from the code you've given.
Note that this has nothing to do with a method returning a bool.
It could be that StockHandler is null, or something in the SaveChangesToFile method is null or invalid.
EDIT
See here:
private StockHelper StockHandler;
StockHandler.SaveChangesToFile(); // = bang :(
You need to initialize the StockHelper instance:
private StockHelper StockHandler = new StockHelper();
StockHandler.SaveChangesToFile(); // = okay :)
I'm assuming that this code doesn't compile, which probably means that StockHandler is null. Otherwise, the error would likely be pointing to the SaveChangesToFile method.
Secondly, you either need to swallow exceptions in the SaveChangesToFile() method (not advisable), or you need to remove the return statement and throw the exception. If you do decide to throw an exception, it should definitely not be an ArgumentException, as it has nothing to do with arguments supplied to the method (or lack thereof).
What is stockhandler -- your SaveChangesToFile method is an instance method -- so have you instantiated a variable 'StockHandler' to an instance of whatever class contains the method SaveChangesToFile();
I started working on this "already started" project, and I'm having a really annoying error when trying to execute some interactions with SQL Server 2008:
The server failed to resume the
transaction. Desc.:
One of these errors I get in this specific method call:
The aspx.cs Call:
busProcesso openProcess = new busProcesso(pProcessoId);
try
{
if (openProcess.GetDocument() == null)
{
//Irrelevant code.
}
}
catch{ //... }
The Business class (relevant part):
public class busProcesso : IbusProcesso
{
public Processo vProcesso { get; set; }
RENDBDataContext db;
public busProcesso()
{
vProcesso = new Processo();
}
public busProcesso(decimal pProcessoId)
{
db = new RENDBDataContext();
try
{
vProcesso = db.Processos.SingleOrDefault(x => x.Id == pProcessoId);
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
public string GetDocument()
{
try
{
string document = null;
foreach (Processo_has_Servico ps in ListaServicosProcesso())
{
if (ps.Servico.Document != null) //Get the error right at this line.
{
document = ps.Servico.Document;
}
}
return document ;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
public IQueryable<Processo_has_Servico> ListaServicosProcesso()
{
db = new RENDBDataContext();
try
{
return from ps in db.Processo_has_Servicos
join s in db.Servicos on ps.Servico_Id equals s.Id
where ps.Processo_Id == vProcesso.Id
select ps;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
}
As I said, the error occurs right at the line:
if (ps.Servico.Document != null) from the GetDocument() method.
Opening SQL Server Activity Monitor, I see there is a process for my database (.Net SqlClient Data Provider)
After some time/use (when I start to get the "server failed to resume the transaction" error), I go to the SQL Server Activity Monitor and there's around 5 or 6 more identical processes that weren't killed and (probably) should've been. When I manually kill them, the error stops for a while, until it starts again.
I'm not really good at working in OO and all, so I'm probably missing something, maybe some way to close one of these connections. Also, any help/tip about this structure will be welcome.
PS. The error doesn't happen everytime. Sometimes it runs just perfectly. Then it starts to give the error. Then it stops. Sometimes it happens just once.. pretty weird.
The code in ListaServicosProcesso is creating the context db. Then it is returning an IQueryable.
At this point no request has been sent to the database.
Then there is a for each in the code. At this point EF says "I need to get the data from the database". So it tries to get the data.
But the context db is now out of scope, so it crashes, on the first line that tries to use the data.
There are 2 ways to get around this:
return a list from ListaServicosProcesso, this will force the database call to execute
move the for each into ListaServicosProcesso
Edit
Pharabus is correct db is not out of scope. The problem is here:
db = new RENDBDataContext();
A new instance of the context is being created without the old one being disposed. Try Dispose of db at the end of ListaServicosProcesso. Even better place db in a using statement. But then the foreach must be moved inside the using statement.
Here's a couple of ideas to try.
1/ You can attach SQL server profiler to see the query that is being executed, which will allow you to copy and paste that query to see the data that is in the database. This might be help.
2/ You never check whether ps.Servico is null - you jump straight to ps.Servico.Document. If ps.Servico is null then you will get a null reference exception if you try to access any properties on that object.
I'm not sure of the exact cause of the error you're seeing (if you Google it, the references are all over the place...), but there are a few things you could improve in your code and I've found that just cleaning things up a bit often makes problems go away. Not always, but often.
I agree with the other answerers that it would help to keep better track of your DataContext(s). For example in you're creating it once in the constructor, then again in ListaServicosProcesso(). At that point vProcesso is on one DataContext and other entities will be on another, which gets messy.
I think you could simplify the whole thing a bit, for example you could combine GetDocument() and ListaServicosProcesso() like this:
public string GetDocument()
{
try
{
// Are you sure vProcesso is not null?
if (vProcesso == null)
return null;
// Only create the context if it wasn't already created,
if (db == null)
db = new RENDBDataContext();
return db.Processo_has_Servicos
.Where(ps => ps.Processo_Id == vProcesso.Id && ps.Servico.Document != null)
.Select(ps => ps.Servico.Document) // use an implicit join
.SingleOrDefault();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}