UNPKG

nice-grpc-web

Version:

A Browser gRPC library that is nice to you

114 lines 4.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeCall = makeCall; const abort_controller_x_1 = require("abort-controller-x"); const nice_grpc_common_1 = require("nice-grpc-common"); const decodeResponse_1 = require("./decodeResponse"); const encodeRequest_1 = require("./encodeRequest"); const makeInternalErrorMessage_1 = require("./makeInternalErrorMessage"); const parseTrailer_1 = require("./parseTrailer"); /** @internal */ async function* makeCall(definition, channel, request, options) { const { metadata, signal = new AbortController().signal, onHeader, onTrailer, } = options; let receivedTrailersOnly = false; let status; let message; function handleTrailer(trailer) { if (receivedTrailersOnly) { if (new Map(trailer).size > 0) { throw new nice_grpc_common_1.ClientError(definition.path, nice_grpc_common_1.Status.INTERNAL, 'Received non-empty trailer after trailers-only response'); } else { return; } } const parsedTrailer = (0, parseTrailer_1.parseTrailer)(trailer); ({ status, message } = parsedTrailer); onTrailer === null || onTrailer === void 0 ? void 0 : onTrailer(parsedTrailer.trailer); } const finalMetadata = (0, nice_grpc_common_1.Metadata)(metadata); finalMetadata.set('content-type', 'application/grpc-web+proto'); finalMetadata.set('x-grpc-web', '1'); const innerAbortController = new AbortController(); const abortListener = () => { innerAbortController.abort(); }; signal.addEventListener('abort', abortListener); let finished = false; let requestError; async function* interceptRequestError() { try { for await (const item of request) { if (finished) { throw new Error('Request finished'); } yield item; } } catch (err) { requestError = { err }; innerAbortController.abort(); throw err; } } async function* handleTransportErrors() { try { return yield* channel.transport({ url: channel.address + definition.path, metadata: finalMetadata, body: (0, encodeRequest_1.encodeRequest)({ request: interceptRequestError(), encode: definition.requestSerialize, }), signal: innerAbortController.signal, method: definition, }); } catch (err) { (0, abort_controller_x_1.rethrowAbortError)(err); throw new nice_grpc_common_1.ClientError(definition.path, nice_grpc_common_1.Status.UNKNOWN, `Transport error: ${(0, makeInternalErrorMessage_1.makeInternalErrorMessage)(err)}`); } } const response = (0, decodeResponse_1.decodeResponse)({ response: handleTransportErrors(), decode: definition.responseDeserialize, onHeader(header) { const isTrailersOnly = header.has('grpc-status'); if (isTrailersOnly) { handleTrailer(header); receivedTrailersOnly = true; } else { onHeader === null || onHeader === void 0 ? void 0 : onHeader(header); } }, onTrailer(trailer) { handleTrailer(trailer); }, }); try { yield* response; } catch (err) { if (requestError !== undefined) { throw requestError.err; } else if (err instanceof nice_grpc_common_1.ClientError || (0, abort_controller_x_1.isAbortError)(err)) { throw err; } else { throw new nice_grpc_common_1.ClientError(definition.path, nice_grpc_common_1.Status.INTERNAL, (0, makeInternalErrorMessage_1.makeInternalErrorMessage)(err)); } } finally { finished = true; signal.removeEventListener('abort', abortListener); if (status != null && status !== nice_grpc_common_1.Status.OK) { throw new nice_grpc_common_1.ClientError(definition.path, status, message !== null && message !== void 0 ? message : ''); } } if (status == null) { throw new nice_grpc_common_1.ClientError(definition.path, nice_grpc_common_1.Status.UNKNOWN, 'Response stream closed without gRPC status. This may indicate a misconfigured CORS policy on the server: Access-Control-Expose-Headers must include "grpc-status" and "grpc-message".'); } } //# sourceMappingURL=makeCall.js.map