Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ def channel_id(self, value: Any):
elif isinstance(value, str):
self._channel_id = ChannelId(value)
else:
raise ValueError(
f"Invalid type for channel_id: {type(value)}. "
"Expected ChannelId or str."
)
from microsoft_agents.activity.errors import activity_errors

raise ValueError(activity_errors.InvalidChannelIdType.format(type(value)))

def _set_validated_channel_id(self, data: Any) -> None:
"""Sets the channel_id after validating it as a ChannelId model."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ def _validate_channel_id(
activity.channel_id.sub_channel
and activity.channel_id.sub_channel != product_info.id
):
raise Exception(
"Conflict between channel_id.sub_channel and productInfo entity"
)
from microsoft_agents.activity.errors import activity_errors

raise Exception(str(activity_errors.ChannelIdProductInfoConflict))
activity.channel_id = ChannelId(
channel=activity.channel_id.channel,
sub_channel=product_info.id,
Expand Down Expand Up @@ -256,9 +256,9 @@ def _serialize_sub_channel_data(
# self.channel_id is the source of truth for serialization
if self.channel_id and self.channel_id.sub_channel:
if product_info and product_info.get("id") != self.channel_id.sub_channel:
raise Exception(
"Conflict between channel_id.sub_channel and productInfo entity"
)
from microsoft_agents.activity.errors import activity_errors

raise Exception(str(activity_errors.ChannelIdProductInfoConflict))
elif not product_info:
if not serialized.get("entities"):
serialized["entities"] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ def __new__(
"""
if isinstance(value, str):
if channel or sub_channel:
raise ValueError(
"If value is provided, channel and sub_channel must be None"
)
from microsoft_agents.activity.errors import activity_errors

raise ValueError(str(activity_errors.ChannelIdValueConflict))

value = value.strip()
if value:
return str.__new__(cls, value)
raise TypeError("value must be a non empty string if provided")
from microsoft_agents.activity.errors import activity_errors

raise TypeError(str(activity_errors.ChannelIdValueMustBeNonEmpty))
else:
if (
not isinstance(channel, str)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
Error resources for Microsoft Agents Activity package.
"""

from .error_message import ErrorMessage
from .error_resources import ActivityErrorResources

# Singleton instance
activity_errors = ActivityErrorResources()

__all__ = ["ErrorMessage", "ActivityErrorResources", "activity_errors"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
ErrorMessage class for formatting error messages with error codes and help URLs.
"""


class ErrorMessage:
"""
Represents a formatted error message with error code and help URL.
This class formats error messages according to the Microsoft Agents SDK pattern:
- Original error message
- Error Code: [negative number]
- Help URL: https://aka.ms/M365AgentsErrorCodes/#anchor
"""

def __init__(
self,
message_template: str,
error_code: int,
help_url_anchor: str = "agentic-identity-with-the-m365-agents-sdk",
):
"""
Initialize an ErrorMessage.
:param message_template: The error message template (may include format placeholders)
:type message_template: str
:param error_code: The error code (should be negative)
:type error_code: int
:param help_url_anchor: The anchor for the help URL (defaults to agentic identity)
:type help_url_anchor: str
"""
self.message_template = message_template
self.error_code = error_code
self.help_url_anchor = help_url_anchor
self.base_url = "https://aka.ms/M365AgentsErrorCodes"

def format(self, *args, **kwargs) -> str:
"""
Format the error message with the provided arguments.
:param args: Positional arguments for string formatting
:param kwargs: Keyword arguments for string formatting
:return: Formatted error message with error code and help URL
:rtype: str
"""
# Format the main message
if args or kwargs:
message = self.message_template.format(*args, **kwargs)
else:
message = self.message_template

# Append error code and help URL
return (
f"{message}\n\n"
f"Error Code: {self.error_code}\n"
f"Help URL: {self.base_url}/#{self.help_url_anchor}"
)

def __str__(self) -> str:
"""Return the formatted error message without any arguments."""
return self.format()

def __repr__(self) -> str:
"""Return a representation of the ErrorMessage."""
return f"ErrorMessage(code={self.error_code}, message='{self.message_template[:50]}...')"
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
Activity error resources for Microsoft Agents SDK.
Error codes are in the range -64000 to -64999.
"""

from .error_message import ErrorMessage


class ActivityErrorResources:
"""
Error messages for activity operations.
Error codes are organized in the range -64000 to -64999.
"""

InvalidChannelIdType = ErrorMessage(
"Invalid type for channel_id: {0}. Expected ChannelId or str.",
-64000,
"activity-schema",
)

ChannelIdProductInfoConflict = ErrorMessage(
"Conflict between channel_id.sub_channel and productInfo entity",
-64001,
"activity-schema",
)

ChannelIdValueConflict = ErrorMessage(
"If value is provided, channel and sub_channel must be None",
-64002,
"activity-schema",
)

ChannelIdValueMustBeNonEmpty = ErrorMessage(
"value must be a non empty string if provided",
-64003,
"activity-schema",
)

InvalidFromPropertyType = ErrorMessage(
"Invalid type for from_property: {0}. Expected ChannelAccount or dict.",
-64004,
"activity-schema",
)

InvalidRecipientType = ErrorMessage(
"Invalid type for recipient: {0}. Expected ChannelAccount or dict.",
-64005,
"activity-schema",
)

def __init__(self):
"""Initialize ActivityErrorResources."""
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
Error resources for Microsoft Agents Authentication MSAL package.
"""

from .error_message import ErrorMessage
from .error_resources import AuthenticationErrorResources

# Singleton instance
authentication_errors = AuthenticationErrorResources()

__all__ = ["ErrorMessage", "AuthenticationErrorResources", "authentication_errors"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
ErrorMessage class for formatting error messages with error codes and help URLs.
"""


class ErrorMessage:
"""
Represents a formatted error message with error code and help URL.
This class formats error messages according to the Microsoft Agents SDK pattern:
- Original error message
- Error Code: [negative number]
- Help URL: https://aka.ms/M365AgentsErrorCodes/#anchor
"""

def __init__(
self,
message_template: str,
error_code: int,
help_url_anchor: str = "agentic-identity-with-the-m365-agents-sdk",
):
"""
Initialize an ErrorMessage.
:param message_template: The error message template (may include format placeholders)
:type message_template: str
:param error_code: The error code (should be negative)
:type error_code: int
:param help_url_anchor: The anchor for the help URL (defaults to agentic identity)
:type help_url_anchor: str
"""
self.message_template = message_template
self.error_code = error_code
self.help_url_anchor = help_url_anchor
self.base_url = "https://aka.ms/M365AgentsErrorCodes"

def format(self, *args, **kwargs) -> str:
"""
Format the error message with the provided arguments.
:param args: Positional arguments for string formatting
:param kwargs: Keyword arguments for string formatting
:return: Formatted error message with error code and help URL
:rtype: str
"""
# Format the main message
if args or kwargs:
message = self.message_template.format(*args, **kwargs)
else:
message = self.message_template

# Append error code and help URL
return (
f"{message}\n\n"
f"Error Code: {self.error_code}\n"
f"Help URL: {self.base_url}/#{self.help_url_anchor}"
)

def __str__(self) -> str:
"""Return the formatted error message without any arguments."""
return self.format()

def __repr__(self) -> str:
"""Return a representation of the ErrorMessage."""
return f"ErrorMessage(code={self.error_code}, message='{self.message_template[:50]}...')"
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
Authentication error resources for Microsoft Agents SDK.
Error codes are in the range -60000 to -60999.
"""

from .error_message import ErrorMessage


class AuthenticationErrorResources:
"""
Error messages for authentication operations.
Error codes are organized in the range -60000 to -60999.
"""

FailedToAcquireToken = ErrorMessage(
"Failed to acquire token. {0}",
-60012,
"agentic-identity-with-the-m365-agents-sdk",
)

InvalidInstanceUrl = ErrorMessage(
"Invalid instance URL",
-60013,
"agentic-identity-with-the-m365-agents-sdk",
)

OnBehalfOfFlowNotSupportedManagedIdentity = ErrorMessage(
"On-behalf-of flow is not supported with Managed Identity authentication.",
-60014,
"agentic-identity-with-the-m365-agents-sdk",
)

OnBehalfOfFlowNotSupportedAuthType = ErrorMessage(
"On-behalf-of flow is not supported with the current authentication type: {0}",
-60015,
"agentic-identity-with-the-m365-agents-sdk",
)

AuthenticationTypeNotSupported = ErrorMessage(
"Authentication type not supported",
-60016,
"agentic-identity-with-the-m365-agents-sdk",
)

AgentApplicationInstanceIdRequired = ErrorMessage(
"Agent application instance Id must be provided.",
-60017,
"agentic-identity-with-the-m365-agents-sdk",
)

FailedToAcquireAgenticInstanceToken = ErrorMessage(
"Failed to acquire agentic instance token or agent token for agent_app_instance_id {0}",
-60018,
"agentic-identity-with-the-m365-agents-sdk",
)

AgentApplicationInstanceIdAndUserIdRequired = ErrorMessage(
"Agent application instance Id and agentic user Id must be provided.",
-60019,
"agentic-identity-with-the-m365-agents-sdk",
)

FailedToAcquireInstanceOrAgentToken = ErrorMessage(
"Failed to acquire instance token or agent token for agent_app_instance_id {0} and agentic_user_id {1}",
-60020,
"agentic-identity-with-the-m365-agents-sdk",
)

def __init__(self):
"""Initialize AuthenticationErrorResources."""
pass
Loading