From 9af4235233c17d7cfd2e059330165fe2c811bb8f Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Sun, 17 Mar 2024 12:38:23 +0800 Subject: [PATCH] skip failed to parse rules and show the timestamp in the UI --- packages/api/src/entity/rule.ts | 3 +++ packages/api/src/generated/graphql.ts | 2 ++ packages/api/src/generated/schema.graphql | 1 + packages/api/src/jobs/trigger_rule.ts | 25 ++++++++++++++----- packages/api/src/schema.ts | 1 + packages/api/src/services/rules.ts | 14 ++++++++++- .../0168.do.add_failed_at_to_rule.sql | 9 +++++++ .../0168.undo.add_failed_at_to_rule.sql | 9 +++++++ .../networking/queries/useGetRulesQuery.tsx | 2 ++ packages/web/pages/settings/rules.tsx | 6 +++++ 10 files changed, 65 insertions(+), 7 deletions(-) create mode 100755 packages/db/migrations/0168.do.add_failed_at_to_rule.sql create mode 100755 packages/db/migrations/0168.undo.add_failed_at_to_rule.sql diff --git a/packages/api/src/entity/rule.ts b/packages/api/src/entity/rule.ts index 0147cbd19..51c63b972 100644 --- a/packages/api/src/entity/rule.ts +++ b/packages/api/src/entity/rule.ts @@ -59,4 +59,7 @@ export class Rule { @UpdateDateColumn({ default: () => 'CURRENT_TIMESTAMP' }) updatedAt!: Date + + @Column('timestamptz') + failedAt?: Date } diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 4e9c0735d..a2a4d7ef8 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -2434,6 +2434,7 @@ export type Rule = { createdAt: Scalars['Date']; enabled: Scalars['Boolean']; eventTypes: Array; + failedAt?: Maybe; filter: Scalars['String']; id: Scalars['ID']; name: Scalars['String']; @@ -6322,6 +6323,7 @@ export type RuleResolvers; enabled?: Resolver; eventTypes?: Resolver, ParentType, ContextType>; + failedAt?: Resolver, ParentType, ContextType>; filter?: Resolver; id?: Resolver; name?: Resolver; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index 60ad805cd..ab001939f 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -1825,6 +1825,7 @@ type Rule { createdAt: Date! enabled: Boolean! eventTypes: [RuleEventType!]! + failedAt: Date filter: String! id: ID! name: String! diff --git a/packages/api/src/jobs/trigger_rule.ts b/packages/api/src/jobs/trigger_rule.ts index 260b7868f..3247e3fa9 100644 --- a/packages/api/src/jobs/trigger_rule.ts +++ b/packages/api/src/jobs/trigger_rule.ts @@ -8,7 +8,7 @@ import { softDeleteLibraryItem, updateLibraryItem, } from '../services/library_item' -import { findEnabledRules } from '../services/rules' +import { findEnabledRules, markRuleAsFailed } from '../services/rules' import { sendPushNotifications } from '../services/user' import { logger } from '../utils/logger' @@ -112,14 +112,27 @@ const triggerActions = async ( query: `(${rule.filter}) AND includes:${itemId}`, } - const libraryItems = await searchLibraryItems(searchArgs, userId) - if (libraryItems.count === 0) { - logger.info(`No pages found for rule ${rule.id}`) + let libraryItem: LibraryItem + + try { + const { libraryItems, count } = await searchLibraryItems( + searchArgs, + userId + ) + if (count === 0) { + logger.info(`No pages found for rule ${rule.id}`) + continue + } + + libraryItem = libraryItems[0] + } catch (error) { + // failed to search for library items, mark rule as failed + logger.error('Error parsing filter in rules', error) + await markRuleAsFailed(rule.id, userId) + continue } - const libraryItem = libraryItems.libraryItems[0] - for (const action of rule.actions) { const actionFunc = getRuleAction(action.type) const actionObj: RuleActionObj = { diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 6c20fb51f..e7eb46a62 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -2152,6 +2152,7 @@ const schema = gql` createdAt: Date! updatedAt: Date eventTypes: [RuleEventType!]! + failedAt: Date } type RuleAction { diff --git a/packages/api/src/services/rules.ts b/packages/api/src/services/rules.ts index bf3637be7..6393a8c40 100644 --- a/packages/api/src/services/rules.ts +++ b/packages/api/src/services/rules.ts @@ -1,4 +1,4 @@ -import { ArrayContains, ILike } from 'typeorm' +import { ArrayContains, ILike, IsNull, Not } from 'typeorm' import { Rule, RuleAction, RuleEventType } from '../entity/rule' import { authTrx, getRepository } from '../repository' @@ -62,5 +62,17 @@ export const findEnabledRules = async ( user: { id: userId }, enabled: true, eventTypes: ArrayContains([eventType]), + failedAt: IsNull(), // only rules that have not failed }) } + +export const markRuleAsFailed = async (id: string, userId: string) => { + return authTrx( + (t) => + t.getRepository(Rule).update(id, { + failedAt: new Date(), + }), + undefined, + userId + ) +} diff --git a/packages/db/migrations/0168.do.add_failed_at_to_rule.sql b/packages/db/migrations/0168.do.add_failed_at_to_rule.sql new file mode 100755 index 000000000..6f77f166c --- /dev/null +++ b/packages/db/migrations/0168.do.add_failed_at_to_rule.sql @@ -0,0 +1,9 @@ +-- Type: DO +-- Name: add_failed_at_to_rule +-- Description: Add failed_at column to rules table + +BEGIN; + +ALTER TABLE omnivore.rules ADD COLUMN failed_at timestamptz; + +COMMIT; diff --git a/packages/db/migrations/0168.undo.add_failed_at_to_rule.sql b/packages/db/migrations/0168.undo.add_failed_at_to_rule.sql new file mode 100755 index 000000000..de2fc769d --- /dev/null +++ b/packages/db/migrations/0168.undo.add_failed_at_to_rule.sql @@ -0,0 +1,9 @@ +-- Type: UNDO +-- Name: add_failed_at_to_rule +-- Description: Add failed_at column to rules table + +BEGIN; + +ALTER TABLE omnivore.rules DROP COLUMN failed_at; + +COMMIT; diff --git a/packages/web/lib/networking/queries/useGetRulesQuery.tsx b/packages/web/lib/networking/queries/useGetRulesQuery.tsx index f7619cdcf..2da718072 100644 --- a/packages/web/lib/networking/queries/useGetRulesQuery.tsx +++ b/packages/web/lib/networking/queries/useGetRulesQuery.tsx @@ -29,6 +29,7 @@ export interface Rule { createdAt: Date updatedAt: Date eventTypes: RuleEventType[] + failedAt?: Date } interface RulesQueryResponse { @@ -62,6 +63,7 @@ export function useGetRulesQuery(): RulesQueryResponse { createdAt updatedAt eventTypes + failedAt } } ... on RulesError { diff --git a/packages/web/pages/settings/rules.tsx b/packages/web/pages/settings/rules.tsx index d38ee76f1..5cf3e1636 100644 --- a/packages/web/pages/settings/rules.tsx +++ b/packages/web/pages/settings/rules.tsx @@ -235,6 +235,7 @@ export default function Rules(): JSX.Element { filter: rule.filter, actions: rule.actions, eventTypes: rule.eventTypes, + failedAt: rule.failedAt, } }) }, [rules]) @@ -318,6 +319,11 @@ export default function Rules(): JSX.Element { ), }, + { + title: 'Failed At', + dataIndex: 'failedAt', + key: 'failedAt', + }, { title: '', key: 'tools',