Skip to content

Handling Exceptional Events

Al Fisher edited this page Dec 19, 2018 · 2 revisions

TL;DR

You can record events in the Log by using

  • BH.Engine.Reflection.Compute.RecordError(string message)
  • BH.Engine.Reflection.Compute.RecordWarning(string message)
  • BH.Engine.Reflection.Compute.RecordNote(string message)

You can access all event logged since the UI was started by calling BH.Engine.Reflection.Query.AllEvents()

Introduction

Things don't always run according to plan. Two typical situations can occur:

  • The input value your method received are invalid or insufficient to generate the output.
  • The methods you call inside your method are failing

In either case, you are generally left with a few choices:

  • throw an exception,
  • return a null value,
  • return a dummy value.

The first option stops the execution of the code completely while the other two allows things to continue but with the risk of the problem remaining unnoticed. A lot of times, none of those options are satisfactory. Let's take a simple example:

public List<object> MyMethod(List<BHoMObject> elements)
{
   List<object> results = new List<object>();
   foreach (BHoMObject element in elements)
      results.Add(DoSomething(element));
   return results;
} 

If DoSomething() throws an exception, this method will fail and pass on the exception. This might be the desired behaviour but we might also want to return all the successful results and just ignore the failing ones. In that case, we could write:

public List<object> MyMethod(List<BHoMObject> elements)
{
   List<object> results = new List<object>();
   foreach (BHoMObject element in elements)
   {
      try 
      {
         results.Add(DoSomething(element));
      }
      catch {}
   }
   return results;
} 

This does the job. But it also hide completely the fact that an error occurred for some of the elements so the results are incomplete.

This is why we have added a log system to the BHoM so all exceptional events can be recorded and passed to the UI.

Recording Events

If we use the log, the code above would look like this:

using BH.Engine.Reflection;

public List<object> MyMethod(List<BHoMObject> elements)
{
   List<object> results = new List<object>();
   foreach (BHoMObject element in elements)
   {
      try 
      {
         results.Add(DoSomething(element));
      }
      catch 
      {
         Compute.RecordWarning("Element " + element.BHoM_Guid + " failed");
      }
   }
   return results;
} 

There 3 levels of event you can record:

  • Error: RecordError()
  • Warning: RecordWarning()
  • Note: RecordNote()

In Grasshopper, they will look like this:

So the UI components will automatically expose all the events that occurred during their execution.

Accessing All Events Since the Start

If you want to get the list of all the events that occurred since you started your script/program, you can use BH.Engine.Reflection.Query.AllEvents(). In Grasshopper, it will look something like this:

As you can see, events are also BHoM object that you can explode as any other typical BHoM object.

What About Exceptions?

Does that mean that we should stop using exception? No!

If your method ends up in a situation where it could not return any meaningful output, it should still throw an exception. Any method that catches an exception, on the other hand, should ALWAYS record something in the Log to make the user aware of what happened.

Clone this wiki locally