feat(attributes): Add device.low_power_mode attribute for iOS#314
feat(attributes): Add device.low_power_mode attribute for iOS#314
Conversation
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Attributes
Other
Bug Fixes 🐛
Documentation 📚
Internal Changes 🔧Deps
Deps Dev
Other
🤖 This preview updates automatically when you update the PR. |
|
|
||
| Type: bool | ||
| Contains PII: false | ||
| Defined in OTEL: No |
There was a problem hiding this comment.
Bug: The new attribute DEVICE_LOW_POWER_MODE was added to ATTRIBUTE_NAMES but is missing its corresponding entry in the ATTRIBUTE_METADATA dictionary in the Python file.
Severity: HIGH
Suggested Fix
Add the missing AttributeMetadata entry for "device.low_power_mode" to the ATTRIBUTE_METADATA dictionary in python/src/sentry_conventions/attributes.py. This will align the Python implementation with the TypeScript version and prevent runtime KeyError exceptions.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: python/src/sentry_conventions/attributes.py#L1535
Potential issue: The Python bindings file was updated to include the new
`DEVICE_LOW_POWER_MODE` constant in the `ATTRIBUTE_NAMES` class. However, the
corresponding entry for this attribute was not added to the `ATTRIBUTE_METADATA`
dictionary. As a result, any Python code that attempts to look up the metadata for this
new attribute, for example by calling `ATTRIBUTE_METADATA["device.low_power_mode"]`,
will encounter a `KeyError` at runtime. This creates an inconsistency where the
attribute constant exists but its metadata is inaccessible.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Python bindings missing metadata and TypedDict entries
- Added device.low_power_mode entries to both ATTRIBUTE_METADATA dictionary and Attributes TypedDict in correct alphabetical position.
- ✅ Fixed: TypeScript Attributes type missing new attribute entry
- Added [DEVICE_LOW_POWER_MODE]?: DEVICE_LOW_POWER_MODE_TYPE entry to the Attributes type in correct alphabetical position.
- ✅ Fixed: New attribute placed in wrong alphabetical position
- Moved all DEVICE_LOW_POWER_MODE entries from after DEVICE_SIMULATOR to between DEVICE_FREE_MEMORY and DEVICE_MEMORY_ESTIMATED_CAPACITY in all sections of both files.
Or push these changes by commenting:
@cursor push 7293ba5b57
Preview (7293ba5b57)
diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts
--- a/javascript/sentry-conventions/src/attributes.ts
+++ b/javascript/sentry-conventions/src/attributes.ts
@@ -2345,6 +2345,26 @@
*/
export type DEVICE_FREE_MEMORY_TYPE = number;
+// Path: model/attributes/device/device__low_power_mode.json
+
+/**
+ * Whether the device is in Low Power Mode. `device.low_power_mode`
+ *
+ * Attribute Value Type: `boolean` {@link DEVICE_LOW_POWER_MODE_TYPE}
+ *
+ * Contains PII: false
+ *
+ * Attribute defined in OTEL: No
+ *
+ * @example true
+ */
+export const DEVICE_LOW_POWER_MODE = 'device.low_power_mode';
+
+/**
+ * Type for {@link DEVICE_LOW_POWER_MODE} device.low_power_mode
+ */
+export type DEVICE_LOW_POWER_MODE_TYPE = boolean;
+
// Path: model/attributes/device/device__memory__estimated_capacity.json
/**
@@ -2469,26 +2489,6 @@
*/
export type DEVICE_SIMULATOR_TYPE = boolean;
-// Path: model/attributes/device/device__low_power_mode.json
-
-/**
- * Whether the device is in Low Power Mode. `device.low_power_mode`
- *
- * Attribute Value Type: `boolean` {@link DEVICE_LOW_POWER_MODE_TYPE}
- *
- * Contains PII: false
- *
- * Attribute defined in OTEL: No
- *
- * @example true
- */
-export const DEVICE_LOW_POWER_MODE = 'device.low_power_mode';
-
-/**
- * Type for {@link DEVICE_LOW_POWER_MODE} device.low_power_mode
- */
-export type DEVICE_LOW_POWER_MODE_TYPE = boolean;
-
// Path: model/attributes/effectiveConnectionType.json
/**
@@ -10347,13 +10347,13 @@
[DEVICE_CLASS]: 'string',
[DEVICE_FAMILY]: 'string',
[DEVICE_FREE_MEMORY]: 'integer',
+ [DEVICE_LOW_POWER_MODE]: 'boolean',
[DEVICE_MEMORY_ESTIMATED_CAPACITY]: 'integer',
[DEVICE_MEMORY_SIZE]: 'integer',
[DEVICE_MODEL]: 'string',
[DEVICE_MODEL_ID]: 'string',
[DEVICE_PROCESSOR_COUNT]: 'integer',
[DEVICE_SIMULATOR]: 'boolean',
- [DEVICE_LOW_POWER_MODE]: 'boolean',
[EFFECTIVECONNECTIONTYPE]: 'string',
[ENVIRONMENT]: 'string',
[ERROR_TYPE]: 'string',
@@ -10836,13 +10836,13 @@
| typeof DEVICE_CLASS
| typeof DEVICE_FAMILY
| typeof DEVICE_FREE_MEMORY
+ | typeof DEVICE_LOW_POWER_MODE
| typeof DEVICE_MEMORY_ESTIMATED_CAPACITY
| typeof DEVICE_MEMORY_SIZE
| typeof DEVICE_MODEL
| typeof DEVICE_MODEL_ID
| typeof DEVICE_PROCESSOR_COUNT
| typeof DEVICE_SIMULATOR
- | typeof DEVICE_LOW_POWER_MODE
| typeof EFFECTIVECONNECTIONTYPE
| typeof ENVIRONMENT
| typeof ERROR_TYPE
@@ -12644,6 +12644,17 @@
example: 2147483648,
changelog: [{ version: 'next', prs: [300], description: 'Added device.free_memory attribute' }],
},
+ [DEVICE_LOW_POWER_MODE]: {
+ brief: 'Whether the device is in Low Power Mode.',
+ type: 'boolean',
+ pii: {
+ isPii: 'false',
+ },
+ isInOtel: false,
+ sdks: ['sentry.cocoa'],
+ example: true,
+ changelog: [{ version: 'next', description: 'Added device.low_power_mode attribute' }],
+ },
[DEVICE_MEMORY_ESTIMATED_CAPACITY]: {
brief:
'The estimated total memory capacity of the device, only a rough estimation in gigabytes. Browsers report estimations in buckets of powers of 2, mostly capped at 8 GB',
@@ -12725,17 +12736,6 @@
example: false,
changelog: [{ version: 'next', prs: [300], description: 'Added device.simulator attribute' }],
},
- [DEVICE_LOW_POWER_MODE]: {
- brief: 'Whether the device is in Low Power Mode.',
- type: 'boolean',
- pii: {
- isPii: 'false',
- },
- isInOtel: false,
- sdks: ['sentry.cocoa'],
- example: true,
- changelog: [{ version: 'next', description: 'Added device.low_power_mode attribute' }],
- },
[EFFECTIVECONNECTIONTYPE]: {
brief: 'Specifies the estimated effective type of the current connection (e.g. slow-2g, 2g, 3g, 4g).',
type: 'string',
@@ -17239,6 +17239,7 @@
[DEVICE_CLASS]?: DEVICE_CLASS_TYPE;
[DEVICE_FAMILY]?: DEVICE_FAMILY_TYPE;
[DEVICE_FREE_MEMORY]?: DEVICE_FREE_MEMORY_TYPE;
+ [DEVICE_LOW_POWER_MODE]?: DEVICE_LOW_POWER_MODE_TYPE;
[DEVICE_MEMORY_ESTIMATED_CAPACITY]?: DEVICE_MEMORY_ESTIMATED_CAPACITY_TYPE;
[DEVICE_MEMORY_SIZE]?: DEVICE_MEMORY_SIZE_TYPE;
[DEVICE_MODEL]?: DEVICE_MODEL_TYPE;
diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py
--- a/python/src/sentry_conventions/attributes.py
+++ b/python/src/sentry_conventions/attributes.py
@@ -1462,6 +1462,16 @@
Example: 2147483648
"""
+ # Path: model/attributes/device/device__low_power_mode.json
+ DEVICE_LOW_POWER_MODE: Literal["device.low_power_mode"] = "device.low_power_mode"
+ """Whether the device is in Low Power Mode.
+
+ Type: bool
+ Contains PII: false
+ Defined in OTEL: No
+ Example: true
+ """
+
# Path: model/attributes/device/device__memory__estimated_capacity.json
DEVICE_MEMORY_ESTIMATED_CAPACITY: Literal["device.memory.estimated_capacity"] = (
"device.memory.estimated_capacity"
@@ -1526,16 +1536,6 @@
Example: false
"""
- # Path: model/attributes/device/device__low_power_mode.json
- DEVICE_LOW_POWER_MODE: Literal["device.low_power_mode"] = "device.low_power_mode"
- """Whether the device is in Low Power Mode.
-
- Type: bool
- Contains PII: false
- Defined in OTEL: No
- Example: true
- """
-
# Path: model/attributes/deviceMemory.json
DEVICEMEMORY: Literal["deviceMemory"] = "deviceMemory"
"""The estimated total memory capacity of the device, only a rough estimation in gigabytes.
@@ -7047,6 +7047,20 @@
),
],
),
+ "device.low_power_mode": AttributeMetadata(
+ brief="Whether the device is in Low Power Mode.",
+ type=AttributeType.BOOLEAN,
+ pii=PiiInfo(isPii=IsPii.FALSE),
+ is_in_otel=False,
+ example=True,
+ sdks=["sentry.cocoa"],
+ changelog=[
+ ChangelogEntry(
+ version="next",
+ description="Added device.low_power_mode attribute",
+ ),
+ ],
+ ),
"device.memory.estimated_capacity": AttributeMetadata(
brief="The estimated total memory capacity of the device, only a rough estimation in gigabytes. Browsers report estimations in buckets of powers of 2, mostly capped at 8 GB",
type=AttributeType.INTEGER,
@@ -11613,6 +11627,7 @@
"device.class": str,
"device.family": str,
"device.free_memory": int,
+ "device.low_power_mode": bool,
"device.memory.estimated_capacity": int,
"device.memory_size": int,
"device.model": str,This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f95b230. Configure here.
| Contains PII: false | ||
| Defined in OTEL: No | ||
| Example: true | ||
| """ |
There was a problem hiding this comment.
Python bindings missing metadata and TypedDict entries
High Severity
The device.low_power_mode attribute's Python bindings are incomplete. While the constant name exists, entries are missing from the ATTRIBUTE_METADATA dictionary and the Attributes TypedDict. This prevents Python consumers from accessing its metadata and type checkers from validating it, making the attribute effectively unusable.
Reviewed by Cursor Bugbot for commit f95b230. Configure here.
| sdks: ['sentry.cocoa'], | ||
| example: true, | ||
| changelog: [{ version: 'next', description: 'Added device.low_power_mode attribute' }], | ||
| }, |
There was a problem hiding this comment.
TypeScript Attributes type missing new attribute entry
Medium Severity
DEVICE_LOW_POWER_MODE is added to the constant, ATTRIBUTE_TYPE map, AttributeName union, and ATTRIBUTE_METADATA, but the Attributes mapped type near line 17247 is missing [DEVICE_LOW_POWER_MODE]?: DEVICE_LOW_POWER_MODE_TYPE;. The entry jumps from DEVICE_SIMULATOR directly to EFFECTIVECONNECTIONTYPE. TypeScript consumers using the Attributes type won't get type-safe access to this new attribute.
Reviewed by Cursor Bugbot for commit f95b230. Configure here.
| /** | ||
| * Type for {@link DEVICE_LOW_POWER_MODE} device.low_power_mode | ||
| */ | ||
| export type DEVICE_LOW_POWER_MODE_TYPE = boolean; |
There was a problem hiding this comment.
New attribute placed in wrong alphabetical position
Low Severity
DEVICE_LOW_POWER_MODE is appended after DEVICE_SIMULATOR in every section (constant definitions, ATTRIBUTE_TYPE, AttributeName, ATTRIBUTE_METADATA, and Python ATTRIBUTE_NAMES), but the rest of the file maintains strict alphabetical order by constant name. Since L sorts before M, P, and S, it belongs between DEVICE_FREE_MEMORY and DEVICE_MEMORY_ESTIMATED_CAPACITY. These are auto-generated files, so the next regeneration will move the entry and produce a noisy diff.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit f95b230. Configure here.



Summary
device.low_power_modeboolean attribute to document whether an iOS device is in Low Power Modesentry.cocoaSDKattributes.ts) and Python (attributes.py) bindingsTest plan
yarn test:jspassesprsfield inmodel/attributes/device/device__low_power_mode.jsonchangelog🤖 Generated with Claude Code