Skip to content

Commit 7aa9227

Browse files
authored
feat(artifacts): Emit granular installable app error codes (EME-883) (#603)
1 parent 48537e6 commit 7aa9227

3 files changed

Lines changed: 30 additions & 20 deletions

File tree

src/launchpad/artifact_processor.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,19 @@ def _do_distribution(
334334
if not apple_info.is_code_signature_valid:
335335
logger.warning(f"BUILD_DISTRIBUTION skipped for {artifact_id}: invalid code signature")
336336
self._update_distribution_error(
337-
organization_id, artifact_id, InstallableAppErrorCode.SKIPPED, "invalid_signature"
337+
organization_id,
338+
artifact_id,
339+
InstallableAppErrorCode.INVALID_CODE_SIGNATURE,
340+
"The build's code signature could not be verified.",
338341
)
339342
return
340343
if apple_info.is_simulator:
341344
logger.warning(f"BUILD_DISTRIBUTION skipped for {artifact_id}: simulator build")
342345
self._update_distribution_error(
343-
organization_id, artifact_id, InstallableAppErrorCode.SKIPPED, "simulator"
346+
organization_id,
347+
artifact_id,
348+
InstallableAppErrorCode.SIMULATOR_BUILD,
349+
"Simulator builds cannot be distributed.",
344350
)
345351
return
346352
with tempfile.TemporaryDirectory() as temp_dir_str:
@@ -368,7 +374,10 @@ def _do_distribution(
368374
else:
369375
logger.error(f"BUILD_DISTRIBUTION failed for {artifact_id}: unsupported artifact type")
370376
self._update_distribution_error(
371-
organization_id, artifact_id, InstallableAppErrorCode.PROCESSING_ERROR, "unsupported artifact type"
377+
organization_id,
378+
artifact_id,
379+
InstallableAppErrorCode.UNSUPPORTED_ARTIFACT_TYPE,
380+
"This artifact type is not supported for distribution.",
372381
)
373382

374383
def _do_size(
@@ -465,7 +474,6 @@ def _update_distribution_error(
465474
"distribution.processing.error",
466475
tags=[
467476
f"error_code:{error_code.value}",
468-
f"error_message:{error_message}",
469477
f"organization_id:{organization_id}",
470478
],
471479
)

src/launchpad/constants.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
from enum import Enum
44

55

6-
# Error code constants (matching the Django model)
6+
# Must stay in sync with PreprodArtifact.ErrorCode in sentry.
77
class ProcessingErrorCode(Enum):
8-
"""Error codes for artifact processing (matching the Django model)."""
9-
108
UNKNOWN = 0
119
UPLOAD_TIMEOUT = 1
1210
ARTIFACT_PROCESSING_TIMEOUT = 2
@@ -29,12 +27,19 @@ class PreprodFeature(Enum):
2927
BUILD_DISTRIBUTION = "build_distribution"
3028

3129

32-
# Matches InstallableApp.ErrorCode in sentry
30+
# Must stay in sync with PreprodArtifact.InstallableAppErrorCode in sentry.
31+
# Adding a value here without adding it on the sentry side will make the
32+
# distribution PUT 400 on pydantic validation.
3333
class InstallableAppErrorCode(Enum):
3434
UNKNOWN = 0
3535
NO_QUOTA = 1
3636
SKIPPED = 2
3737
PROCESSING_ERROR = 3
38+
DISTRIBUTION_DISABLED = 4
39+
DISTRIBUTION_FILTERED = 5
40+
INVALID_CODE_SIGNATURE = 6
41+
SIMULATOR_BUILD = 7
42+
UNSUPPORTED_ARTIFACT_TYPE = 8
3843

3944

4045
# Health check threshold - consider unhealthy if file not touched in 60 seconds

tests/unit/artifacts/test_artifact_processor.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,14 @@ def test_do_distribution_unknown_artifact_type_reports_error(self):
155155
org="test-org-id",
156156
artifact_id="test-artifact-id",
157157
data={
158-
"error_code": InstallableAppErrorCode.PROCESSING_ERROR.value,
159-
"error_message": "unsupported artifact type",
158+
"error_code": InstallableAppErrorCode.UNSUPPORTED_ARTIFACT_TYPE.value,
159+
"error_message": "This artifact type is not supported for distribution.",
160160
},
161161
)
162162
mock_statsd.increment.assert_called_once_with(
163163
"distribution.processing.error",
164164
tags=[
165-
f"error_code:{InstallableAppErrorCode.PROCESSING_ERROR.value}",
166-
"error_message:unsupported artifact type",
165+
f"error_code:{InstallableAppErrorCode.UNSUPPORTED_ARTIFACT_TYPE.value}",
167166
"organization_id:test-org-id",
168167
],
169168
)
@@ -186,15 +185,14 @@ def test_do_distribution_invalid_code_signature_reports_skip(self):
186185
org="test-org-id",
187186
artifact_id="test-artifact-id",
188187
data={
189-
"error_code": InstallableAppErrorCode.SKIPPED.value,
190-
"error_message": "invalid_signature",
188+
"error_code": InstallableAppErrorCode.INVALID_CODE_SIGNATURE.value,
189+
"error_message": "The build's code signature could not be verified.",
191190
},
192191
)
193192
mock_statsd.increment.assert_called_once_with(
194193
"distribution.processing.error",
195194
tags=[
196-
f"error_code:{InstallableAppErrorCode.SKIPPED.value}",
197-
"error_message:invalid_signature",
195+
f"error_code:{InstallableAppErrorCode.INVALID_CODE_SIGNATURE.value}",
198196
"organization_id:test-org-id",
199197
],
200198
)
@@ -218,15 +216,14 @@ def test_do_distribution_simulator_build_reports_skip(self):
218216
org="test-org-id",
219217
artifact_id="test-artifact-id",
220218
data={
221-
"error_code": InstallableAppErrorCode.SKIPPED.value,
222-
"error_message": "simulator",
219+
"error_code": InstallableAppErrorCode.SIMULATOR_BUILD.value,
220+
"error_message": "Simulator builds cannot be distributed.",
223221
},
224222
)
225223
mock_statsd.increment.assert_called_once_with(
226224
"distribution.processing.error",
227225
tags=[
228-
f"error_code:{InstallableAppErrorCode.SKIPPED.value}",
229-
"error_message:simulator",
226+
f"error_code:{InstallableAppErrorCode.SIMULATOR_BUILD.value}",
230227
"organization_id:test-org-id",
231228
],
232229
)

0 commit comments

Comments
 (0)