| 1 | import { PlatformErrorCategory } from '../platforms/platforms.exception' |
| 2 | |
| 3 | export interface MetaGraphError { |
| 4 | message?: string |
| 5 | type?: string |
| 6 | code?: number |
| 7 | error_subcode?: number |
| 8 | is_transient?: boolean |
| 9 | error_data?: unknown |
| 10 | error_user_title?: string |
| 11 | error_user_msg?: string |
| 12 | fbtrace_id?: string |
| 13 | } |
| 14 | |
| 15 | export interface MetaGraphErrorBody { |
| 16 | error?: MetaGraphError |
| 17 | } |
| 18 | |
| 19 | export function metaGraphPlatformCode(error?: MetaGraphError): number | undefined { |
| 20 | return error?.code ?? error?.error_subcode |
| 21 | } |
| 22 | |
| 23 | export function categoryFromMetaGraphError( |
| 24 | status: number, |
| 25 | error?: MetaGraphError, |
| 26 | endpoint?: string, |
| 27 | ): PlatformErrorCategory { |
| 28 | const code = error?.code |
| 29 | const subcode = error?.error_subcode |
| 30 | |
| 31 | if (error?.error_subcode === 2207069) { |
| 32 | return PlatformErrorCategory.Quota |
| 33 | } |
| 34 | if ( |
| 35 | code === 190 |
| 36 | || code === 102 |
| 37 | || isMetaAuthSubcode(subcode) |
| 38 | || (error?.type === 'OAuthException' && code === undefined && subcode === undefined) |
| 39 | || status === 401 |
| 40 | || (status === 400 && endpoint?.includes('/oauth/')) |
| 41 | ) { |
| 42 | return PlatformErrorCategory.Auth |
| 43 | } |
| 44 | if (code === 4 || code === 17 || code === 341 || status === 429) { |
| 45 | return PlatformErrorCategory.RateLimit |
| 46 | } |
| 47 | if (code === 3 || code === 10 || isMetaPermissionCode(code) || status === 403) { |
| 48 | return PlatformErrorCategory.Permission |
| 49 | } |
| 50 | if (code === 506 || status === 409) { |
| 51 | return PlatformErrorCategory.Conflict |
| 52 | } |
| 53 | if (code === 100 || code === 1609005 || status === 400 || status === 422) { |
| 54 | return PlatformErrorCategory.Validation |
| 55 | } |
| 56 | if (code === 1 || code === 2 || code === 368 || status >= 500) { |
| 57 | return PlatformErrorCategory.PlatformUnavailable |
| 58 | } |
| 59 | if (status === 404) { |
| 60 | return PlatformErrorCategory.NotFound |
| 61 | } |
| 62 | return PlatformErrorCategory.Unknown |
| 63 | } |
| 64 | |
| 65 | export function isMetaGraphErrorRetryable(status: number, error?: MetaGraphError): boolean { |
| 66 | const code = error?.code |
| 67 | const category = categoryFromMetaGraphError(status, error) |
| 68 | if ( |
| 69 | category === PlatformErrorCategory.Auth |
| 70 | || category === PlatformErrorCategory.Permission |
| 71 | || category === PlatformErrorCategory.Validation |
| 72 | || category === PlatformErrorCategory.Conflict |
| 73 | || category === PlatformErrorCategory.NotFound |
| 74 | || category === PlatformErrorCategory.Quota |
| 75 | ) { |
| 76 | return false |
| 77 | } |
| 78 | if (error?.is_transient === true) { |
| 79 | return true |
| 80 | } |
| 81 | if (code === 100) { |
| 82 | return false |
| 83 | } |
| 84 | return status === 408 |
| 85 | || status === 429 |
| 86 | || status >= 500 |
| 87 | || code === 1 |
| 88 | || code === 2 |
| 89 | || code === 4 |
| 90 | || code === 17 |
| 91 | || code === 341 |
| 92 | || code === 368 |
| 93 | } |
| 94 | |
| 95 | function isMetaAuthSubcode(subcode?: number): boolean { |
| 96 | return subcode === 458 |
| 97 | || subcode === 459 |
| 98 | || subcode === 460 |
| 99 | || subcode === 463 |
| 100 | || subcode === 464 |
| 101 | || subcode === 467 |
| 102 | || subcode === 492 |
| 103 | } |
| 104 | |
| 105 | function isMetaPermissionCode(code?: number): boolean { |
| 106 | return code !== undefined && code >= 200 && code <= 299 |
| 107 | } |
| 108 |