Customize application errors with Programmatic Errors

Programmatic Errors allow you to customize errors, monitor and troubleshoot issues that should not necessarily interfere with the service. For example, an application trying to remove a user who doesn't exist. These custom errors can be handled by adding just a few lines of code.

Programmatic Errors are labelled as warnings to indicate that a non fatal error occurred, such as application error. You can log programmatic errors, track custom error issues, and trigger Alerts.


Configuring a Generic Error

Programmatic Errors can be configured from anywhere within your Lambda handler’s code. Below are some examples using the Lumigo tracer integrations.

console.log("[LUMIGO_LOG] <YOUR_MESSAGE>");
System.out.println("[LUMIGO_LOG] <YOUR_MESSAGE>");

Configuring a Custom Error

To configure custom types of errors, use one of the three options listed below:

  1. Lumigo tracer logger:
import lumigo_tracer
lumigo_tracer.error("a description of the error", "My Custom Type")
const lumigo = require('@lumigo/tracer');
lumigo.error("a description of the error", { type: "My Custom Type" });
  1. Logging with Lumigo format:
error = {
    'message': 'a description of the error',
    'type': 'My Custom Type'
print("[LUMIGO_LOG]", json.dumps(error))
let error = {
    'message': 'a description of the error',
    'type': 'My Custom Type'
console.log(`[LUMIGO_LOG] ${JSON.stringify(error)}`);
  1. Logging in pure JSON format:
  • For field 'message' you can alternatively use 'event'.
  • For field 'type' you can alternatively use 'exception_name', 'exception_type'
    'message': '[LUMIGO_LOG] a description of the error',
    'type': 'My Custom Type' 
let error = {
	'message': '[LUMIGO_LOG] a description of the error',
	'type': 'My Custom Type'


Note that when configuring programmatic errors the type error field is case sensitive and length specific. For example, setting an error with the type “Error 42 “ will cause the associated errors to aggregate differently to “error 42” on the issues page.

OpenTelemetry and Containers

Programmatic errors are created by adding span events with a custom attribute being set with the key name lumigo.type.

For example, you could add a programmatic error as follows:

from opentelemetry.trace import get_current_span
get_current_span().add_event('<error-message>', {'lumigo.type': '<error-type>'})
const { trace } = require('@opentelemetry/api');
trace.getActiveSpan()?.addEvent('<error-message>', {'lumigo.type': '<error-type>'});
Attributes eventAttributes = Attributes.of(
    AttributeKey.stringKey("lumigo.type"), "<error-type>"
Span.current().addEvent("<error-message>", eventAttributes);


A Twilio SMS API discards outgoing SMS requests that contain an empty message body, but does not return an error indication, this can be handled using programmatic errors.

Twilio returns multiple error messages for different cases. Since you may care more about some of these errors and less about others, looking at all of the errors through a single lens (for example, as generic 4xx or "client errors") could be very inefficient. You can use a custom programmatic error type for each of the cases.

If we look at a 400 response returned from Twilio as part of the example:

    "code": 14108,
    "message": "Invalid Phone Number",
    "more_info": "",
    "status": 400

Then the code can use that to report Lumigo Programmatic Errors in the following way:

response = twilio_client.messages.create(body=sms.message,
        from_=sms.sender, to=sms.recepient)

if response.status == 400:
    if response.code == 14108:
        lumigo.error(response.message, 'Twilio: Invalid Phone Number')
    elif response.code == 32103:
        lumigo.error(response.message, 'Twilio: Empty SMS Body')
        lumigo.error(response.message, 'Twilio: Client Error')

Resulting in multiple issues grouped by issue type as defined from our code example above.


Example: Custom programmatic errors propagated to Lumigo