Skip to content

Commit

Permalink
Merge branch 'master' into contributing-md
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkamyshev committed Apr 10, 2024
2 parents fde1c15 + d0fc25b commit 27e979d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/fuzzy-cooks-join.md
@@ -0,0 +1,5 @@
---
"@farfetched/core": patch
---

Fix bug with extra fires of `finished.failure` in case of failed contract application with `retry` operator
2 changes: 1 addition & 1 deletion packages/core/package.json
Expand Up @@ -41,7 +41,7 @@
"size-limit": [
{
"path": "./dist/core.js",
"limit": "16.1 kB"
"limit": "16.2 kB"
}
]
}
37 changes: 35 additions & 2 deletions packages/core/src/remote_operation/create_remote_operation.ts
Expand Up @@ -152,6 +152,11 @@ export function createRemoteOperation<
error: Error | InvalidDataError;
meta: ExecutionMeta;
}>();
const failedIgnoreSuppression = createEvent<{
params: Params;
error: Error | InvalidDataError;
meta: ExecutionMeta;
}>();
const aborted = createEvent<{
params: Params;
meta: ExecutionMeta;
Expand Down Expand Up @@ -283,7 +288,10 @@ export function createRemoteOperation<
fn: ({ params, result }) => ({
params: params.params,
result: result.result as Data,
meta: { stopErrorPropagation: false, stale: result.stale },
meta: {
stopErrorPropagation: result.stopErrorPropagation ?? false,
stale: result.stale,
},
}),
filter: $enabled,
target: applyContractFx,
Expand Down Expand Up @@ -373,6 +381,17 @@ export function createRemoteOperation<
target: failedNoFilters,
});

sample({
clock: applyContractFx.fail,
fn: ({ error, params }) => ({
error,
// Extract original params, it is params of params
params: params.params,
meta: params.meta,
}),
target: failedIgnoreSuppression,
});

sample({
clock: invalidDataRecieved,
filter: ({ meta }) => !meta.stopErrorPropagation,
Expand All @@ -387,6 +406,19 @@ export function createRemoteOperation<
target: failedNoFilters,
});

sample({
clock: invalidDataRecieved,
fn: ({ params, validation, meta, result }) => ({
params,
error: invalidDataError({
validationErrors: unwrapValidationResult(validation),
response: result,
}),
meta,
}),
target: failedIgnoreSuppression,
});

// Emit skip for disabling in-flight operation
sample({
clock: $enabled.updates,
Expand Down Expand Up @@ -463,6 +495,7 @@ export function createRemoteOperation<
pushData,
startWithMeta,
callObjectCreated,
failedIgnoreSuppression,
},
},
};
Expand All @@ -475,7 +508,7 @@ function createDataSourceHandlers<Params>(dataSources: DataSource<Params>[]) {
skipStale?: boolean;
meta: ExecutionMeta;
},
{ result: unknown; stale: boolean },
{ result: unknown; stale: boolean; stopErrorPropagation?: boolean },
{ stopErrorPropagation: boolean; error: unknown }
>({
handler: async ({ params, skipStale }) => {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/remote_operation/type.ts
Expand Up @@ -122,6 +122,11 @@ export interface RemoteOperation<
pushError: EventCallable<Error>;
startWithMeta: EventCallable<{ params: Params; meta: ExecutionMeta }>;
callObjectCreated: Event<CallObject>;
failedIgnoreSuppression: Event<{
params: Params;
error: Error;
meta: ExecutionMeta;
}>;
} & ExtraLowLevelAPI;
experimentalAPI?: {
attach: <Source, NewParams>(config: {
Expand Down
35 changes: 35 additions & 0 deletions packages/core/src/retry/__tests__/retry.test.ts
Expand Up @@ -4,6 +4,8 @@ import { allSettled, createWatch, fork } from 'effector';
import { unknownContract } from '../../contract/unknown_contract';
import { createJsonMutation } from '../../mutation/create_json_mutation';
import { httpError } from '../../errors/create_error';
import { createJsonQuery } from '../../query/create_json_query';
import { fetchFx } from '../../fetch/fetch';
import { retry } from '../retry';

describe('retry', () => {
Expand Down Expand Up @@ -48,4 +50,37 @@ describe('retry', () => {

expect(onFailure).toBeCalledTimes(1);
});

test('does supress contract failure error as well, issue #459', async () => {
const q = createJsonQuery({
request: { url: 'https://api.salo.com', method: 'GET' },
response: {
contract: {
isData(v): v is unknown {
return false;
},
getErrorMessages(v) {
return ['Failed contract'];
},
},
},
});

retry(q, { times: 1, delay: 1 });

const scope = fork({
handlers: [[fetchFx, () => new Response('{"data": "ok"}')]],
});

const failedListener = vi.fn();
createWatch({ unit: q.finished.failure, scope, fn: failedListener });

const startedListener = vi.fn();
createWatch({ unit: q.started, scope, fn: startedListener });

await allSettled(q.start, { scope });

expect(startedListener).toBeCalledTimes(2 /* Initial and retry */);
expect(failedListener).toBeCalledTimes(1 /* Only latest failure */);
});
});
7 changes: 6 additions & 1 deletion packages/core/src/retry/retry.ts
Expand Up @@ -160,6 +160,11 @@ export function retry<
const originalFx =
operation.__.lowLevelAPI.dataSourceRetrieverFx.use.getCurrent();

sample({
clock: operation.__.lowLevelAPI.failedIgnoreSuppression,
target: failed,
});

operation.__.lowLevelAPI.dataSourceRetrieverFx.use(
attach({
source: { supressError: $supressError, partialFilter: $partialFilter },
Expand All @@ -182,7 +187,7 @@ export function retry<
try {
const result = await originalFx(opts);

return result;
return { ...result, stopErrorPropagation: supressError };
} catch (error: any) {
const failInfo = {
params: opts.params,
Expand Down

0 comments on commit 27e979d

Please sign in to comment.