BaseHandler.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. import { ApolloError, OperationVariables } from '@apollo/client/core'
  3. import {
  4. BaseHandlerOptions,
  5. CommonHandlerOptions,
  6. CommonHandlerOptionsParameter,
  7. OperationResult,
  8. OperationReturn,
  9. } from '@common/types/server/apollo/handler'
  10. import { Ref } from 'vue'
  11. import useNotifications from '@common/composables/useNotifications'
  12. import { NotificationTypes } from '@common/types/notification'
  13. import {
  14. GraphQLErrorReport,
  15. GraphQLErrorTypes,
  16. GraphQLHandlerError,
  17. } from '@common/types/error'
  18. export default abstract class BaseHandler<
  19. TResult = OperationResult,
  20. TVariables = OperationVariables,
  21. TOperationReturn extends OperationReturn<
  22. TResult,
  23. TVariables
  24. > = OperationReturn<TResult, TVariables>,
  25. THandlerOptions = BaseHandlerOptions,
  26. > {
  27. public operationResult!: TOperationReturn
  28. protected baseHandlerOptions: BaseHandlerOptions = {
  29. errorShowNotification: true,
  30. errorNotitifactionMessage: __(
  31. 'An error occured during the operation. Please contact your administrator.',
  32. ),
  33. errorNotitifactionType: NotificationTypes.ERROR,
  34. }
  35. public handlerOptions!: CommonHandlerOptions<THandlerOptions>
  36. constructor(
  37. operationResult: TOperationReturn,
  38. handlerOptions?: CommonHandlerOptionsParameter<THandlerOptions>,
  39. ) {
  40. this.operationResult = operationResult
  41. this.handlerOptions = this.mergedHandlerOptions(handlerOptions)
  42. this.initialize()
  43. }
  44. protected initialize(): void {
  45. this.operationResult.onError((error) => {
  46. this.handleError(error)
  47. })
  48. }
  49. public loading(): Ref<boolean> {
  50. return this.operationResult.loading
  51. }
  52. public operationError(): Ref<Maybe<ApolloError>> {
  53. return this.operationResult.error
  54. }
  55. protected handleError(error: ApolloError): void {
  56. const options = this.handlerOptions
  57. if (options.errorShowNotification) {
  58. const { notify } = useNotifications()
  59. notify({
  60. message: options.errorNotitifactionMessage,
  61. type: options.errorNotitifactionType,
  62. })
  63. }
  64. if (options.errorCallback) {
  65. const { graphQLErrors, networkError } = error
  66. let errorHandler: GraphQLHandlerError
  67. if (graphQLErrors.length > 0) {
  68. const { message, extensions }: GraphQLErrorReport = graphQLErrors[0]
  69. errorHandler = {
  70. type:
  71. (extensions?.type as GraphQLErrorTypes) ||
  72. GraphQLErrorTypes.NetworkError,
  73. message,
  74. }
  75. } else if (networkError) {
  76. errorHandler = {
  77. type: GraphQLErrorTypes.NetworkError,
  78. }
  79. } else {
  80. errorHandler = {
  81. type: GraphQLErrorTypes.UnkownError,
  82. }
  83. }
  84. options.errorCallback(errorHandler)
  85. }
  86. }
  87. protected mergedHandlerOptions(
  88. handlerOptions?: CommonHandlerOptionsParameter<THandlerOptions>,
  89. ): CommonHandlerOptions<THandlerOptions> {
  90. // The merged type is always safe as a 'CommonHandlerOptions<THandlerOptions>' type.
  91. return Object.assign(
  92. this.baseHandlerOptions,
  93. handlerOptions,
  94. ) as CommonHandlerOptions<THandlerOptions>
  95. }
  96. }