Skip to content

Commit bdcd085

Browse files
committed
codex-localized-error-presentation: localize semantic error presentation
1 parent a5cbb77 commit bdcd085

49 files changed

Lines changed: 2061 additions & 1922 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎build/api/index.js‎

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77

88

99
Object.defineProperty(exports, "__esModule", ({ value: true }));
10-
exports.ApplicationError = exports.APPLICATION_ERROR_METADATA = void 0;
10+
exports.ApplicationError = exports.APPLICATION_ERROR_RECOVERY_IDS = exports.APPLICATION_ERROR_METADATA = void 0;
1111
exports.toApplicationError = toApplicationError;
1212
const application_error_1 = __nccwpck_require__(7790);
1313
const application_error_context_1 = __nccwpck_require__(4034);
1414
var application_error_2 = __nccwpck_require__(7790);
1515
Object.defineProperty(exports, "APPLICATION_ERROR_METADATA", ({ enumerable: true, get: function () { return application_error_2.APPLICATION_ERROR_METADATA; } }));
16+
Object.defineProperty(exports, "APPLICATION_ERROR_RECOVERY_IDS", ({ enumerable: true, get: function () { return application_error_2.APPLICATION_ERROR_RECOVERY_IDS; } }));
1617
/** Creates a semantic error and owns correlation identity outside the pure model. */
1718
class ApplicationError extends application_error_1.ApplicationError {
1819
constructor(code, message, options = {}) {
@@ -4528,8 +4529,16 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
45284529
};
45294530
var _ApplicationError_cause;
45304531
Object.defineProperty(exports, "__esModule", ({ value: true }));
4531-
exports.ApplicationError = exports.APPLICATION_ERROR_METADATA = void 0;
4532+
exports.ApplicationError = exports.APPLICATION_ERROR_METADATA = exports.APPLICATION_ERROR_RECOVERY_IDS = void 0;
45324533
exports.isApplicationErrorCorrelationId = isApplicationErrorCorrelationId;
4534+
exports.APPLICATION_ERROR_RECOVERY_IDS = Object.freeze([
4535+
'pull-request-link-restored',
4536+
'pull-request-link-base-retained',
4537+
'pull-request-link-reference-retained',
4538+
'pull-request-link-base-and-reference-retained',
4539+
'managed-branch-enrichment-failed',
4540+
'inactivity-explanation-failed',
4541+
]);
45334542
const PRESERVED_STATE = 'Existing persisted state and completed external effects were preserved.';
45344543
const UNCHANGED_STATE = 'No new state or external effect was created.';
45354544
exports.APPLICATION_ERROR_METADATA = {
@@ -4677,10 +4686,11 @@ class ApplicationError extends Error {
46774686
this.code = code;
46784687
this.kind = metadata.kind;
46794688
this.retryable = options.retryable ?? metadata.retryable;
4680-
this.impact = options.impact ?? metadata.impact;
4681-
this.action = options.action ?? metadata.action;
4682-
this.retainedState = options.retainedState ?? metadata.retainedState;
4689+
this.impact = metadata.impact;
4690+
this.action = metadata.action;
4691+
this.retainedState = metadata.retainedState;
46834692
this.correlationId = correlationId;
4693+
this.recovery = normalizeApplicationErrorRecovery(options.recovery);
46844694
__classPrivateFieldSet(this, _ApplicationError_cause, options.cause, "f");
46854695
}
46864696
toJSON() {
@@ -4694,11 +4704,49 @@ class ApplicationError extends Error {
46944704
action: this.action,
46954705
retainedState: this.retainedState,
46964706
correlationId: this.correlationId,
4707+
...(this.recovery ? { recovery: this.recovery } : {}),
46974708
};
46984709
}
46994710
}
47004711
exports.ApplicationError = ApplicationError;
47014712
_ApplicationError_cause = new WeakMap();
4713+
const RECOVERY_VARIABLE_KEYS = Object.freeze({
4714+
'pull-request-link-restored': Object.freeze([]),
4715+
'pull-request-link-base-retained': Object.freeze([]),
4716+
'pull-request-link-reference-retained': Object.freeze([]),
4717+
'pull-request-link-base-and-reference-retained': Object.freeze([]),
4718+
'managed-branch-enrichment-failed': Object.freeze(['branchName']),
4719+
'inactivity-explanation-failed': Object.freeze(['issueNumber']),
4720+
});
4721+
function normalizeApplicationErrorRecovery(recovery) {
4722+
if (!recovery)
4723+
return undefined;
4724+
if (!exports.APPLICATION_ERROR_RECOVERY_IDS.includes(recovery.id)) {
4725+
throw new TypeError('Application error recovery ID is invalid.');
4726+
}
4727+
const variables = recovery.variables;
4728+
const actualKeys = Object.keys(variables).sort();
4729+
const expectedKeys = [...RECOVERY_VARIABLE_KEYS[recovery.id]].sort();
4730+
if (actualKeys.length !== expectedKeys.length
4731+
|| actualKeys.some((key, index) => key !== expectedKeys[index])) {
4732+
throw new TypeError(`Application error recovery variables are invalid for ${recovery.id}.`);
4733+
}
4734+
if (recovery.id === 'managed-branch-enrichment-failed'
4735+
&& (typeof variables.branchName !== 'string'
4736+
|| !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,254}$/u.test(variables.branchName))) {
4737+
throw new TypeError('Application error recovery branch name is invalid.');
4738+
}
4739+
if (recovery.id === 'inactivity-explanation-failed'
4740+
&& (typeof variables.issueNumber !== 'number'
4741+
|| !Number.isSafeInteger(variables.issueNumber)
4742+
|| variables.issueNumber < 1)) {
4743+
throw new TypeError('Application error recovery issue number is invalid.');
4744+
}
4745+
return Object.freeze({
4746+
id: recovery.id,
4747+
variables: Object.freeze({ ...variables }),
4748+
});
4749+
}
47024750

47034751

47044752
/***/ }),
@@ -5338,7 +5386,7 @@ exports.renderCatalogMessage = renderCatalogMessage;
53385386
exports.catalogPlaceholders = catalogPlaceholders;
53395387
exports.catalogPluralCategories = catalogPluralCategories;
53405388
const locale_1 = __nccwpck_require__(5386);
5341-
exports.MESSAGE_CATALOG_VERSION = '1';
5389+
exports.MESSAGE_CATALOG_VERSION = '2';
53425390
exports.CATALOG_PLURAL_CATEGORIES = Object.freeze([
53435391
'zero',
53445392
'one',

‎build/api/src/application/errors/application_error.d.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ApplicationError as SemanticApplicationError, type ApplicationErrorCode, type SemanticApplicationErrorOptions } from '../../data/model/application_error';
2-
export { APPLICATION_ERROR_METADATA, type ApplicationErrorCode, type ApplicationErrorKind, type ApplicationErrorPublicRecord, } from '../../data/model/application_error';
2+
export { APPLICATION_ERROR_METADATA, APPLICATION_ERROR_RECOVERY_IDS, type ApplicationErrorCode, type ApplicationErrorKind, type ApplicationErrorPublicRecord, type ApplicationErrorRecovery, type ApplicationErrorRecoveryId, } from '../../data/model/application_error';
33
export interface ApplicationErrorOptions extends Omit<SemanticApplicationErrorOptions, 'correlationId'> {
44
readonly correlationId?: string;
55
}

‎build/api/src/data/model/application_error.d.ts‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
export type ApplicationErrorKind = 'configuration' | 'authorization' | 'provider' | 'agent' | 'validation' | 'workflow' | 'unknown';
22
export type ApplicationErrorCode = 'configuration.invalid' | 'configuration.unsupported' | 'authorization.denied' | 'authorization.credential-invalid' | 'provider.not-found' | 'provider.conflict' | 'provider.rate-limited' | 'provider.unavailable' | 'provider.contract-invalid' | 'agent.policy-rejected' | 'agent.failed' | 'locale.output-invalid' | 'locale.translation-failed' | 'validation.invalid-input' | 'workflow.invalid-event' | 'workflow.stale' | 'workflow.cancelled' | 'workflow.failed' | 'timeout' | 'unexpected';
3+
export declare const APPLICATION_ERROR_RECOVERY_IDS: readonly ["pull-request-link-restored", "pull-request-link-base-retained", "pull-request-link-reference-retained", "pull-request-link-base-and-reference-retained", "managed-branch-enrichment-failed", "inactivity-explanation-failed"];
4+
export type ApplicationErrorRecoveryId = typeof APPLICATION_ERROR_RECOVERY_IDS[number];
5+
interface ApplicationErrorRecoveryVariables {
6+
readonly 'pull-request-link-restored': Readonly<Record<string, never>>;
7+
readonly 'pull-request-link-base-retained': Readonly<Record<string, never>>;
8+
readonly 'pull-request-link-reference-retained': Readonly<Record<string, never>>;
9+
readonly 'pull-request-link-base-and-reference-retained': Readonly<Record<string, never>>;
10+
readonly 'managed-branch-enrichment-failed': Readonly<{
11+
branchName: string;
12+
}>;
13+
readonly 'inactivity-explanation-failed': Readonly<{
14+
issueNumber: number;
15+
}>;
16+
}
17+
export type ApplicationErrorRecovery = {
18+
readonly [Id in ApplicationErrorRecoveryId]: Readonly<{
19+
id: Id;
20+
variables: ApplicationErrorRecoveryVariables[Id];
21+
}>;
22+
}[ApplicationErrorRecoveryId];
323
interface ApplicationErrorMetadata {
424
readonly kind: ApplicationErrorKind;
525
readonly retryable: boolean;
@@ -10,9 +30,7 @@ interface ApplicationErrorMetadata {
1030
export declare const APPLICATION_ERROR_METADATA: Readonly<Record<ApplicationErrorCode, ApplicationErrorMetadata>>;
1131
export interface SemanticApplicationErrorOptions {
1232
readonly retryable?: boolean;
13-
readonly impact?: string;
14-
readonly action?: string;
15-
readonly retainedState?: string;
33+
readonly recovery?: ApplicationErrorRecovery;
1634
readonly correlationId: string;
1735
readonly cause?: unknown;
1836
}
@@ -26,6 +44,7 @@ export interface ApplicationErrorPublicRecord {
2644
readonly action: string;
2745
readonly retainedState: string;
2846
readonly correlationId: string;
47+
readonly recovery?: ApplicationErrorRecovery;
2948
}
3049
export declare function isApplicationErrorCorrelationId(value: string): boolean;
3150
/** Semantic error contract whose public fields are safe to serialize and present. */
@@ -39,6 +58,7 @@ export declare class ApplicationError extends Error {
3958
readonly action: string;
4059
readonly retainedState: string;
4160
readonly correlationId: string;
61+
readonly recovery?: ApplicationErrorRecovery;
4262
constructor(code: ApplicationErrorCode, message: string, options: SemanticApplicationErrorOptions);
4363
toJSON(): ApplicationErrorPublicRecord;
4464
}

‎build/api/src/domain/message_catalog.d.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export declare const MESSAGE_CATALOG_VERSION = "1";
1+
export declare const MESSAGE_CATALOG_VERSION = "2";
22
export type CatalogResolutionSource = 'exact' | 'base' | 'dynamic' | 'fallback';
33
export type CatalogFallbackReason = 'dynamic-provider-unavailable' | 'dynamic-response-invalid' | 'dynamic-request-failed';
44
export declare const CATALOG_PLURAL_CATEGORIES: readonly ["zero", "one", "two", "few", "many", "other"];

0 commit comments

Comments
 (0)