Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(core): Handle GraphQLError[] value in error observer callback of subscriptionExchange (#3346)

authored by

Phil Pluckthun and committed by
GitHub
f9ea1db4 51f67ade

+30 -13
+6
.changeset/shy-maps-raise.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Add case for `subscriptionExchange` to handle `GraphQLError[]` received in the `error` observer callback. 6 + **Note:** This doesn't strictly check for the `GraphQLError` shape and only checks for arrays and receiving errors in the `ExecutionResult` on the `next` observer callback is preferred and recommended for transports.
+24 -13
packages/core/src/exchanges/subscription.ts
··· 144 144 operation 145 145 ); 146 146 147 - return make<OperationResult>(({ next, complete }) => { 147 + return make<OperationResult>(observer => { 148 148 let isComplete = false; 149 149 let sub: Subscription | void; 150 150 let result: OperationResult | void; 151 + 152 + function nextResult(value: ExecutionResult) { 153 + observer.next( 154 + (result = result 155 + ? mergeResultPatch(result, value) 156 + : makeResult(operation, value)) 157 + ); 158 + } 151 159 152 160 Promise.resolve().then(() => { 153 161 if (isComplete) return; 154 162 155 163 sub = observableish.subscribe({ 156 - next(nextResult) { 157 - next( 158 - (result = result 159 - ? mergeResultPatch(result, nextResult) 160 - : makeResult(operation, nextResult)) 161 - ); 162 - }, 164 + next: nextResult, 163 165 error(error) { 164 - next(makeErrorResult(operation, error)); 166 + if (Array.isArray(error)) { 167 + // NOTE: This is an exception for transports that deliver `GraphQLError[]`, as part 168 + // of the observer’s error callback (may happen as part of `graphql-ws`). 169 + // We only check for arrays here, as this is an extremely “unexpected” case as the 170 + // shape of `ExecutionResult` is instead strictly defined. 171 + nextResult({ errors: error }); 172 + } else { 173 + observer.next(makeErrorResult(operation, error)); 174 + } 175 + observer.complete(); 165 176 }, 166 177 complete() { 167 178 if (!isComplete) { ··· 171 182 makeOperation('teardown', operation, operation.context) 172 183 ); 173 184 } 174 - 175 - if (result && result.hasNext) 176 - next(mergeResultPatch(result, { hasNext: false })); 177 - complete(); 185 + if (result && result.hasNext) { 186 + nextResult({ hasNext: false }); 187 + } 188 + observer.complete(); 178 189 } 179 190 }, 180 191 });