( organizationId: string, )
| 137 | * defect. |
| 138 | */ |
| 139 | const organizationFromDatabase = ( |
| 140 | organizationId: string, |
| 141 | ): Effect.Effect< |
| 142 | { readonly id: string; readonly name: string; readonly slug?: string }, |
| 143 | McpSessionMetaUnavailableError | OrganizationNotFoundError, |
| 144 | UserStoreService | WorkOSClient |
| 145 | > => |
| 146 | Effect.gen(function* () { |
| 147 | let attempts = 0; |
| 148 | // `Effect.retry` retries every failure it sees, so definitive failures are |
| 149 | // lifted OUT of the error channel before the schedule ever runs and only |
| 150 | // the retryable ones are left in it. |
| 151 | const attempt = Effect.suspend(() => { |
| 152 | attempts += 1; |
| 153 | return resolveOrganization(organizationId).pipe( |
| 154 | Effect.result, |
| 155 | Effect.flatMap((outcome) => |
| 156 | Result.isFailure(outcome) && isRetryableOrganizationLookupFailure(outcome.failure) |
| 157 | ? Effect.fail(outcome.failure) |
| 158 | : Effect.succeed(outcome), |
| 159 | ), |
| 160 | ); |
| 161 | }); |
| 162 | |
| 163 | // Two nested Results: the outer one is "the retries ran out", the inner one |
| 164 | // is "the lookup failed definitively on the first look". Both mean the same |
| 165 | // thing to the caller. |
| 166 | const retried = yield* attempt.pipe(Effect.retry(RETRY_SCHEDULE), Effect.result); |
| 167 | const outcome = Result.isFailure(retried) ? Result.fail(retried.failure) : retried.success; |
| 168 | |
| 169 | if (Result.isFailure(outcome)) { |
| 170 | return yield* new McpSessionMetaUnavailableError({ |
| 171 | reason: failureReason(outcome.failure), |
| 172 | attempts, |
| 173 | }); |
| 174 | } |
| 175 | const organization = outcome.success; |
| 176 | if (!organization) return yield* new OrganizationNotFoundError({ organizationId }); |
| 177 | return organization; |
| 178 | }).pipe( |
| 179 | Effect.withSpan("mcp.session.resolve_organization", { |
| 180 | attributes: { "mcp.auth.organization_id": organizationId }, |
| 181 | }), |
| 182 | ); |
| 183 | |
| 184 | /** |
| 185 | * Build the session meta for an init, preferring the org identity the request |
no test coverage detected