Extract http response resolution

master
dev 5 months ago
parent 164e6fb9db
commit 37a5e008f5

@ -31,6 +31,7 @@ Estado al cierre:
- `arts/conn/connection.ts` delega la programacion de reconnect y exhaustion en `connection-reconnect-runtime.ts`.
- `libs/perm/evaluator.ts` delega helpers puros de resultado, dependencias y comparacion en `evaluator-helpers.ts`.
- `arts/http/engine-http.ts` delega la validacion preflight de `bodySchema` en `request-validation.ts`.
- `arts/http/engine-http.ts` delega la resolucion final de response/error en `response-resolution.ts`.
- `arts/sium/core/pipe.ts` queda centrado en composicion; factories `refine/transform/codec/meta` viven en `steps.ts`.
- `arts/conn/connection.ts` delega decode/routing de frames entrantes en `connection-message-router.ts`.
- `arts/conn/connection.ts` delega el intento open/auth/flush/join en `connection-connect.ts`.

@ -10,9 +10,6 @@ import {
HTTP_METHOD_PATCH,
HTTP_METHOD_POST,
HTTP_METHOD_PUT,
HTTP_RESULT_KIND_NETWORK,
HTTP_RESULT_KIND_VALIDATION,
httpStatusErrorMessage,
HTTP_DIAGNOSTIC_EVENTS
} from './consts.ts';
import { emitHttpDiagnostic } from './diagnostics.ts';
@ -24,14 +21,12 @@ import {
type ResolvedHttpDefaults
} from './engine-options.ts';
import {
runAfterResponse,
runBeforeError,
runBeforeRequest,
runBeforeRetry
} from './hooks.ts';
import { computeRetryDelay, delayWithSignal, shouldRetryRequest } from './retry.ts';
import { buildHttpFailure, buildOkOrValidation } from './results.ts';
import { validateHttpRequestBody } from './request-validation.ts';
import { resolveHttpFinalResult } from './response-resolution.ts';
import { appendSearch, normalizeSearch, resolveUrl } from './search.ts';
import {
attemptTimeoutSignal,
@ -48,7 +43,6 @@ import type {
HttpGetInit,
HttpInit,
HttpMethod,
HttpResult,
HttpResultPromise,
Out
} from './types.ts';
@ -240,65 +234,16 @@ async function execute<S extends StandardSchemaV1 | undefined>(
// shipped.
const finalCtx: HookContext = lastCtx!;
if (response !== undefined) {
// Success path may run afterResponse to swap the response.
const finalResponse = await runAfterResponse(hooks.afterResponse, finalCtx, response);
if (finalResponse.ok) {
const result = await buildOkOrValidation<S>(
finalResponse,
method,
init !== undefined ? init.schema : undefined
);
// Validation failure on a 2xx body is a contract violation between
// client and server — log at ERROR so it surfaces independently of
// the result handling path.
if (!result.ok && result.kind === HTTP_RESULT_KIND_VALIDATION) {
emitHttpDiagnostic(diagnostics, HTTP_DIAGNOSTIC_EVENTS.RESPONSE_SCHEMA_FAILED, {
method,
url: fullUrl,
issueCount: result.issues.length
});
}
return result;
}
// Non-2xx: try to rescue via beforeError, else build http result.
const rescued = await runBeforeError(
hooks.beforeError,
{ ...finalCtx, response: finalResponse },
lastError ?? new Error(httpStatusErrorMessage(finalResponse.status))
);
if (rescued instanceof Response) {
return await buildOkOrValidation<S>(
rescued,
method,
init !== undefined ? init.schema : undefined
);
}
// Log non-2xx as WARN — common enough to be expected (4xx mostly), but
// still useful in DevTools for diagnosing routing/auth/rate limits.
emitHttpDiagnostic(diagnostics, HTTP_DIAGNOSTIC_EVENTS.HTTP_STATUS, {
method,
url: fullUrl,
status: finalResponse.status,
statusText: finalResponse.statusText
});
return buildHttpFailure<S>(finalResponse, method);
}
// No response: network or abort. Try beforeError rescue path.
const rescued = await runBeforeError(hooks.beforeError, finalCtx, lastError);
if (rescued instanceof Response) {
return await buildOkOrValidation<S>(
rescued,
method,
init !== undefined ? init.schema : undefined
);
}
return { ok: false, kind: HTTP_RESULT_KIND_NETWORK, error: lastError } as HttpResult<Out<S>>;
return resolveHttpFinalResult({
diagnostics,
hooks,
method,
fullUrl,
schema: init !== undefined ? init.schema : undefined,
finalCtx,
response,
lastError
});
}
function classifyFetchError(err: unknown, signal: AbortSignal): unknown {

@ -0,0 +1,82 @@
import type { StandardSchemaV1 } from '$libs/standard-schema';
import {
HTTP_DIAGNOSTIC_EVENTS,
HTTP_RESULT_KIND_NETWORK,
HTTP_RESULT_KIND_VALIDATION,
httpStatusErrorMessage
} from './consts.ts';
import { emitHttpDiagnostic, type HttpDiagnostics } from './diagnostics.ts';
import { runAfterResponse, runBeforeError } from './hooks.ts';
import { buildHttpFailure, buildOkOrValidation } from './results.ts';
import type {
HookContext,
HttpHooks,
HttpMethod,
HttpResult,
Out
} from './types.ts';
interface ResolveHttpFinalResultInput<S extends StandardSchemaV1 | undefined> {
readonly diagnostics: HttpDiagnostics;
readonly hooks: Required<HttpHooks>;
readonly method: HttpMethod;
readonly fullUrl: string;
readonly schema: S | undefined;
readonly finalCtx: HookContext;
readonly response: Response | undefined;
readonly lastError: unknown;
}
export async function resolveHttpFinalResult<S extends StandardSchemaV1 | undefined>(
input: ResolveHttpFinalResultInput<S>
): Promise<HttpResult<Out<S>>> {
const { diagnostics, hooks, method, fullUrl, schema, finalCtx, response, lastError } = input;
if (response !== undefined) {
// Success path may run afterResponse to swap the response.
const finalResponse = await runAfterResponse(hooks.afterResponse, finalCtx, response);
if (finalResponse.ok) {
const result = await buildOkOrValidation<S>(finalResponse, method, schema);
// Validation failure on a 2xx body is a contract violation between
// client and server — log at ERROR so it surfaces independently of
// the result handling path.
if (!result.ok && result.kind === HTTP_RESULT_KIND_VALIDATION) {
emitHttpDiagnostic(diagnostics, HTTP_DIAGNOSTIC_EVENTS.RESPONSE_SCHEMA_FAILED, {
method,
url: fullUrl,
issueCount: result.issues.length
});
}
return result;
}
// Non-2xx: try to rescue via beforeError, else build http result.
const rescued = await runBeforeError(
hooks.beforeError,
{ ...finalCtx, response: finalResponse },
lastError ?? new Error(httpStatusErrorMessage(finalResponse.status))
);
if (rescued instanceof Response) {
return await buildOkOrValidation<S>(rescued, method, schema);
}
// Log non-2xx as WARN — common enough to be expected (4xx mostly), but
// still useful in DevTools for diagnosing routing/auth/rate limits.
emitHttpDiagnostic(diagnostics, HTTP_DIAGNOSTIC_EVENTS.HTTP_STATUS, {
method,
url: fullUrl,
status: finalResponse.status,
statusText: finalResponse.statusText
});
return buildHttpFailure<S>(finalResponse, method);
}
// No response: network or abort. Try beforeError rescue path.
const rescued = await runBeforeError(hooks.beforeError, finalCtx, lastError);
if (rescued instanceof Response) {
return await buildOkOrValidation<S>(rescued, method, schema);
}
return { ok: false, kind: HTTP_RESULT_KIND_NETWORK, error: lastError } as HttpResult<Out<S>>;
}
Loading…
Cancel
Save

Powered by TurnKey Linux.