Description
Summary
After comparing the Python and TypeScript implementations of AWS Lambda Powertools Metrics, I found a number of runtime validations that are present in the Python version but missing in the TypeScript version. These missing validations could lead to potential issues in production if not addressed.
Overall TypeScript version relies heavily on compile-time type safety without adequate runtime safeguards, and in certain cases, it allows invalid data to be passed at runtime.
Why is this needed?
The TypeScript implementation is missing several critical runtime validations that are present in the Python version:
- Metric Value Validation: No runtime check for numeric values
- Metric Unit Validation: No runtime validation against valid CloudWatch units
- Metric Resolution Validation: No runtime validation for resolution values (1 or 60)
- Dimension Name Validation: Only validates dimension values, not names, and allows whitespace-only strings
These missing validations could lead to:
- Invalid metrics being sent to CloudWatch
- Runtime errors when invalid data is passed
- Silent failures where metrics are dropped by CloudWatch
- Inconsistent behavior between Python and TypeScript implementations
Which area does this relate to?
Metrics
Solution
1. Runtime Metric Value Type Validation
The Python implementation includes a runtime check to ensure that metric values are valid numbers. If a non-numeric value is passed, it raises a MetricValueError
.
Python code:
if not isinstance(value, numbers.Number):
raise MetricValueError(f"{value} is not a valid number")
The TypeScript implementation has no runtime validation if types are bypassed or incorrect values passed.
TypeScript Source - addMetric method
2. Runtime Metric Unit Validation
The Python implementation validates that the metric unit is one of the valid CloudWatch units at runtime. If an invalid unit is passed, it raises a MetricUnitError
.
Python code:
def _extract_metric_unit_value(self, unit: str | MetricUnit) -> str:
if isinstance(unit, str):
if unit in self._metric_unit_valid_options:
unit = MetricUnit[unit].value
if unit not in self._metric_units:
raise MetricUnitError(
f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_valid_options}",
)
The TypeScript implementation relies solely on TypeScript enum types and does not perform any runtime validation against valid CloudWatch units.
TypeScript Source - MetricUnit constants
3. Runtime Metric Resolution Validation
The Python implementation includes a runtime check to ensure that metric resolution values are valid integers (1 or 60). If an invalid resolution is passed, it raises a MetricResolutionError
.
Python code:
def _extract_metric_resolution_value(self, resolution: int | MetricResolution) -> int:
if isinstance(resolution, int) and resolution in self._metric_resolutions:
return resolution
raise MetricResolutionError(
f"Invalid metric resolution '{resolution}', expected either option: {self._metric_resolutions}",
)
The TypeScript implementation does not perform any runtime validation for resolution values.
TypeScript Source - MetricResolution constants
4. Dimension Name Validation
The Python implementation includes validation for dimension names and values, ensuring they are non-empty strings and not just whitespace. If a dimension name or value is invalid, it raises a PowertoolsUserWarning
.
Python code:
if not name.strip() or not value.strip():
warnings.warn(
f"The dimension {name} doesn't meet the requirements and won't be added. "
"Ensure the dimension name and value are non-empty strings",
category=PowertoolsUserWarning,
stacklevel=2,
)
return
The TypeScript implementation only checks if the value is truthy, which means it does not validate dimension names at all and allows whitespace-only strings.
TypeScript code:
// Only validates value, NOT name
if (!value) {
this.#logger.warn(
`The dimension ${name} doesn't meet the requirements and won't be added. Ensure the dimension name and value are non empty strings`
);
return;
}
Acknowledgment
- This request meets Powertools for AWS Lambda (TypeScript) Tenets
- Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status