4

I'm trying to implement some error handling into my C# code for my .NET application. I feel like I'm missing something really obvious because I know there has to be a way to do this, but I just can't figure it out. I have a python script I call out to using gp.Execute(). If there is an error in the python script and it does not complete, I cannot get the message from it, because any call like gp.GetMessages() has to come after the gp.Execute() statement, so it never gets hit if the script encounters an error and execution stops in my C# code. How do you get error messages from your scripts? I have also tried to put gp.GetMessages() in the catch statement but the gp object is considered out of scope there.

My current code:

try {
     //stuff here

     //Run PopulatePatches script
     IGeoProcessor2 gp = new GeoProcessorClass();
     gp.AddToolbox(@"C:\Users\mxxx\Desktop\GIS_Testing\HbtatTesting\HabitatMon.tbx");
     IVariantArray parameters = new VarArrayClass();
     parameters.Add(shapefile);
     gp.Execute("PopulatePatches", parameters, null);
     gp.GetMessages(ref sev) //never hits this line if python script fails
}
catch {
     ViewBag.Message = "Failed!";
     return View();
}

Lastly, I have gotten rid of the try/catch block and tried to just get the script to play through by doing this:

IGeoProcessorResult pResult = gp.Execute("PopulatePatches", parameters, null)
int severity = 2;
string messages = pResult.GetMessages(severity);

//I have also attempted the above line with just straight gp.GetMessages(severity) 
//because I think result objects are null if the tool doesn't execute properly

ViewBag.Message = messages;
return View();

It will always stop on the execute call, throwing the general HResult E_FAIL COMException in .NET even though I know the error is a ZeroDivisionError in the script because I purposely put it in there (the code runs perfect in python and my .NET app if I fix the zero division error).

3
  • 1
    Just a wild guess: you could try to move the gp = new GeoProcessorclass() before try, and then call gp.getMessages() inside the catch block. (In fact, the only thing you want to try is the call to Execute)
    – Berend
    Commented Nov 9, 2017 at 14:18
  • @Berend If I could upvote you 100 million times, I would. I've been trying to figure this out for ages and that solution works perfectly. I don't know why it didn't occur to me to just move gp out into the local scope...
    – MKF
    Commented Nov 9, 2017 at 14:34
  • Good to hear. I'll copy my comment to an answer.
    – Berend
    Commented Nov 9, 2017 at 15:30

1 Answer 1

6

To get the messages in the catch block, the gp variable needs to be accessible outside try.

You could also use finally if you want to get the messages regardless of success.

IGeoProcessor2 gp = new GeoProcessorClass();
gp.AddToolbox(@"C:\Users\mxxx\Desktop\GIS_Testing\HbtatTesting\HabitatMon.tbx");
IVariantArray parameters = new VarArrayClass();
parameters.Add(shapefile);

try 
{
     gp.Execute("PopulatePatches", parameters, null);
}
catch 
{
     ViewBag.Message = "Failed!";
}
finally
{
     var messages = gp.GetMessages(ref sev);
     // Do something useful with messages

     return View();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.