Exceptions and Error Handling#
NeMo Guardrails supports raising exceptions from within flows.
An exception is an event whose name ends with Exception
, e.g., InputRailException
.
When an exception is raised, the final output is a message with the role set to exception
and the content
set to additional information about the exception. For example:
define flow input rail example
# ...
create event InputRailException(message="Input not allowed.")
{
"role": "exception",
"content": {
"type": "InputRailException",
"uid": "45a452fa-588e-49a5-af7a-0bab5234dcc3",
"event_created_at": "9999-99-99999:24:30.093749+00:00",
"source_uid": "NeMoGuardrails",
"message": "Input not allowed."
}
}
Guardrails Library Exception#
By default, all the guardrails included in the Guardrails Library return a predefined message
when a rail is triggered. You can change this behavior by setting the enable_rails_exceptions
key to True
in your
config.yml
file:
enable_rails_exceptions: True
When this setting is enabled, the rails are triggered, they will return an exception message.
To understand better what is happening under the hood, here’s how the self check input
rail is implemented:
define flow self check input
$allowed = execute self_check_input
if not $allowed
if $config.enable_rails_exceptions
create event InputRailException(message="Input not allowed. The input was blocked by the 'self check input' flow.")
else
bot refuse to respond
stop
Note
In Colang 2.x, you must change $config.enable_rails_exceptions
to $system.config.enable_rails_exceptions
and create event
to send
.
When the self check input
rail is triggered, the following exception is returned.
{
"role": "exception",
"content": {
"type": "InputRailException",
"uid": "45a452fa-588e-49a5-af7a-0bab5234dcc3",
"event_created_at": "9999-99-99999:24:30.093749+00:00",
"source_uid": "NeMoGuardrails",
"message": "Input not allowed. The input was blocked by the 'self check input' flow."
}
}
Exception Types#
NeMo Guardrails supports several predefined exception types:
InputRailException#
Raised when input rails block or reject user input.
define flow custom input check
if $user_message contains "forbidden_word"
create event InputRailException(message="Input contains forbidden content.")
OutputRailException#
Raised when output rails block or reject bot responses.
define flow custom output check
if $bot_message contains "sensitive_info"
create event OutputRailException(message="Output contains sensitive information.")
DialogRailException#
Raised when dialog rails encounter issues during conversation flow.
define flow topic restriction
if $user_intent == "ask_about_restricted_topic"
create event DialogRailException(message="This topic is not allowed in the current context.")
RetrievalRailException#
Raised when retrieval rails encounter issues with document retrieval.
define flow retrieval validation
if len($relevant_chunks) == 0
create event RetrievalRailException(message="No relevant information found for the query.")
Custom Exception Handling#
You can create custom exception types by following the naming convention of ending with Exception
:
define flow custom validation
if not $custom_condition
create event CustomValidationException(message="Custom validation failed.")
Exception Response Format#
All exceptions follow a consistent JSON format:
{
"role": "exception",
"content": {
"type": "ExceptionType",
"uid": "unique-identifier",
"event_created_at": "timestamp",
"source_uid": "source-identifier",
"message": "Human-readable error message"
}
}
Field Descriptions#
type: The exception type (e.g.,
InputRailException
)uid: A unique identifier for the exception instance
event_created_at: Timestamp when the exception was created
source_uid: Identifier for the source that created the exception
message: Human-readable description of what went wrong
Handling Exceptions in Applications#
When integrating NeMo Guardrails with your application, you should handle exceptions appropriately:
from nemoguardrails import LLMRails, RailsConfig
config = RailsConfig.from_path("./config")
rails = LLMRails(config)
try:
response = rails.generate(messages=[{"role": "user", "content": "Hello"}])
if response.get("role") == "exception":
# Handle the exception
exception_content = response.get("content", {})
exception_type = exception_content.get("type")
exception_message = exception_content.get("message")
# Log the exception or take appropriate action
print(f"Exception {exception_type}: {exception_message}")
# Provide fallback response to user
fallback_response = "I'm sorry, but I cannot process that request at the moment."
else:
# Process normal response
print(response.get("content", ""))
except Exception as e:
# Handle other errors
print(f"Error: {e}")
Best Practices#
Use Descriptive Messages: Provide clear, actionable error messages in your exceptions.
Log Exceptions: Always log exceptions for debugging and monitoring purposes.
Graceful Degradation: Provide fallback responses when exceptions occur.
User-Friendly Messages: Translate technical exception messages into user-friendly responses.
Exception Categories: Use appropriate exception types to categorize different kinds of errors.
Configuration Control: Use the
enable_rails_exceptions
setting to control whether rails return exceptions or predefined messages.
Integration with Tracing#
Exceptions are automatically captured by the tracing system when enabled. This allows you to:
Monitor exception frequency and types
Track which rails are triggering exceptions
Analyze patterns in user inputs that cause exceptions
Debug and improve rail configurations
For more information on tracing, see the Tracing Configuration guide.