Skip to content

Commit

Permalink
Let mockLink.onError return false to prevent observer.error.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn authored and hwillson committed Oct 10, 2020
1 parent a2bf2c2 commit d1ce23e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 21 deletions.
22 changes: 17 additions & 5 deletions src/link/core/ApolloLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,25 @@ export class ApolloLink {
throw new InvariantError('request is not implemented');
}

protected onError(error: any, observer: ZenObservable.Observer<FetchResult>) {
observer.error!(error);
protected onError(
error: any,
observer: ZenObservable.Observer<FetchResult>,
): false | void {
if (observer && observer.error) {
observer.error(error);
// Returning false indicates that observer.error does not need to be
// called again, since it was already called (on the previous line).
// Calling observer.error again would not cause any real problems,
// since only the first call matters, but custom onError functions
// might have other reasons for wanting to prevent the default
// behavior by returning false.
return false;
}
// Throw errors will be passed to observer.error.
throw error;
}

public setOnError(
fn: (error: any, observer?: ZenObservable.Observer<FetchResult>) => any
): this {
public setOnError(fn: ApolloLink["onError"]): this {
this.onError = fn;
return this;
}
Expand Down
38 changes: 22 additions & 16 deletions src/utilities/testing/mocking/mockLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,35 @@ export class MockLink extends ApolloLink {
}

return new Observable(observer => {
let timer = setTimeout(
() => {
if (configError) {
try {
this.onError(configError, observer);
} catch (error) {
observer.error(error);
const timer = setTimeout(() => {
if (configError) {
try {
// The onError function can return false to indicate that
// configError need not be passed to observer.error. For
// example, the default implementation of onError calls
// observer.error(configError) and then returns false to
// prevent this extra (harmless) observer.error call.
if (this.onError(configError, observer) !== false) {
throw configError;
}
} else if (response!.error) {
observer.error(response!.error);
} catch (error) {
observer.error(error);
}
} else if (response) {
if (response.error) {
observer.error(response.error);
} else {
if (response!.result) {
if (response.result) {
observer.next(
typeof response!.result === 'function'
? (response!.result as ResultFunction<FetchResult>)()
: response!.result
typeof response.result === 'function'
? (response.result as ResultFunction<FetchResult>)()
: response.result
);
}
observer.complete();
}
},
response?.delay || 0
);
}
}, response && response.delay || 0);

return () => {
clearTimeout(timer);
Expand Down

0 comments on commit d1ce23e

Please sign in to comment.