Skip to content

Commit

Permalink
add error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
sywhb committed Mar 7, 2024
1 parent 8207c49 commit 41022ae
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 59 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ yarn.lock
dist
.vscode/
*.log
.DS_Store
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
},
"homepage": "https://github.com/omnivore-app/omnivore-api#readme",
"dependencies": {
"gql.tada": "^1.2.1",
"gql.tada": "^1.3.1",
"urql": "^4.0.6"
},
"devDependencies": {
"@0no-co/graphqlsp": "^1.4.1",
"@0no-co/graphqlsp": "^1.4.2",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"eslint": "^8.57.0",
Expand Down
81 changes: 33 additions & 48 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client, fetchExchange } from 'urql'
import { buildOmnivoreError } from './errors'
import { graphql } from './graphql'

export interface ClientOptions {
Expand Down Expand Up @@ -317,61 +318,50 @@ export class Omnivore {
const { data, error } = await this._client
.query(SearchQuery, params)
.toPromise()
if (error) {
throw new Error(`Search error: ${error.message}`)
const search = data?.search
if (error || !search || search.__typename === 'SearchError') {
const err = buildOmnivoreError(search, error)
console.error('Search error', err)
throw err
}

if (!data) {
throw new Error('Search error: No data returned')
}

if (data.search.__typename === 'SearchError') {
throw new Error(`Search error: ${data.search.errorCodes.join(', ')}`)
}

return data.search
return search
}

async updatesSince(since: string): Promise<UpdatesSinceResponse> {
const { data, error } = await this._client
.query(UpdatesSinceQuery, { since })
.toPromise()
if (error) {
throw new Error(`UpdatesSince error: ${error.message}`)
}

if (!data) {
throw new Error('UpdatesSince error: No data returned')
}

if (data.updatesSince.__typename === 'UpdatesSinceError') {
throw new Error(
`UpdatesSince error: ${data.updatesSince.errorCodes.join(', ')}`,
)
const updatesSince = data?.updatesSince
if (
error ||
!updatesSince ||
updatesSince.__typename === 'UpdatesSinceError'
) {
const err = buildOmnivoreError(updatesSince, error)
console.error('UpdatesSince error', err)
throw err
}

return data.updatesSince
return updatesSince
}

async delete(id: string): Promise<DeleteResponse> {
const { data, error } = await this._client
.mutation(DeleteMutation, { input: { articleID: id, bookmark: false } })
.toPromise()
if (error) {
throw new Error(`Delete error: ${error.message}`)
}

if (!data) {
throw new Error('Delete error: No data returned')
}

if (data.setBookmarkArticle.__typename === 'SetBookmarkArticleError') {
throw new Error(
`Delete error: ${data.setBookmarkArticle.errorCodes.join(', ')}`,
)
const deleteArticle = data?.setBookmarkArticle
if (
error ||
!deleteArticle ||
deleteArticle.__typename === 'SetBookmarkArticleError'
) {
const err = buildOmnivoreError(deleteArticle, error)
console.error('Delete error', err)
throw err
}

return { id: data.setBookmarkArticle.bookmarkedArticle.id }
return { id: deleteArticle.bookmarkedArticle.id }
}

async saveByURL(params: SaveByURLParameters): Promise<SaveByURLResponse> {
Expand All @@ -384,18 +374,13 @@ export class Omnivore {
},
})
.toPromise()
if (error) {
throw new Error(`SaveByURL error: ${error.message}`)
}

if (!data) {
throw new Error('SaveByURL error: No data returned')
}

if (data.saveUrl.__typename === 'SaveError') {
throw new Error(`SaveByURL error: ${data.saveUrl.errorCodes.join(', ')}`)
const saveUrl = data?.saveUrl
if (error || !saveUrl || saveUrl.__typename === 'SaveError') {
const err = buildOmnivoreError(saveUrl, error)
console.error('SaveByURL error', err)
throw err
}

return { id: data.saveUrl.clientRequestId }
return { id: saveUrl.clientRequestId }
}
}
55 changes: 55 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { CombinedError } from 'urql'

export enum OmnivoreErrorCode {
GraphQLError = 'GRAPHQL_ERROR',
NetworkError = 'NETWORK_ERROR',
UnknownError = 'UNKNOWN_ERROR',
}

abstract class OmnivoreErrorBase<Code extends OmnivoreErrorCode> extends Error {
abstract code: Code
}

class GraphQLError extends OmnivoreErrorBase<OmnivoreErrorCode> {
code = OmnivoreErrorCode.GraphQLError
constructor(public messages?: string[]) {
super(messages?.join(', '))
}
}

class NetworkError extends OmnivoreErrorBase<OmnivoreErrorCode> {
code = OmnivoreErrorCode.NetworkError
constructor(public message: string) {
super(message)
}
}

class UnknownError extends OmnivoreErrorBase<OmnivoreErrorCode> {
code = OmnivoreErrorCode.UnknownError
constructor(public message: string) {
super(message)
}
}

export type OmnivoreError = GraphQLError | NetworkError | UnknownError

export const buildOmnivoreError = (
data?: { __typename: string; errorCodes?: string[] },
error?: CombinedError,
): OmnivoreError => {
if (error) {
if (error.graphQLErrors.length > 0) {
return new GraphQLError(error.graphQLErrors.map((e) => e.message))
}

if (error.networkError) {
return new NetworkError(error.networkError.message)
}
}

if (!data) {
return new UnknownError('No data returned')
}

return new GraphQLError(data.errorCodes)
}
21 changes: 12 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
export {
Omnivore,
SearchParameters,
SearchResponse,
UpdatesSinceResponse,
SaveByURLParameters,
Node,
PageInfo,
PageType,
SaveByURLResponse,
ClientOptions,
DeleteResponse,
Highlight,
HighlightType,
Label,
Node,
Omnivore,
PageInfo,
PageType,
SaveByURLParameters,
SaveByURLResponse,
SearchParameters,
SearchResponse,
UpdatesSinceResponse,
} from './client'

export { OmnivoreError, OmnivoreErrorCode } from './errors'

0 comments on commit 41022ae

Please sign in to comment.