BaseHandler.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright (C) 2012-2021 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. errorNotitifactionType: NotificationTypes.ERROR,
  33. }
  34. public handlerOptions!: CommonHandlerOptions<THandlerOptions>
  35. constructor(
  36. operationResult: TOperationReturn,
  37. handlerOptions?: CommonHandlerOptionsParameter<THandlerOptions>,
  38. ) {
  39. this.operationResult = operationResult
  40. this.handlerOptions = this.mergedHandlerOptions(handlerOptions)
  41. this.initialize()
  42. }
  43. protected initialize(): void {
  44. this.operationResult.onError((error) => {
  45. this.handleError(error)
  46. })
  47. }
  48. public loading(): Ref<boolean> {
  49. return this.operationResult.loading
  50. }
  51. public operationError(): Ref<Maybe<ApolloError>> {
  52. return this.operationResult.error
  53. }
  54. protected handleError(error: ApolloError): void {
  55. const options = this.handlerOptions
  56. if (options.errorShowNotification) {
  57. const { notify } = useNotifications()
  58. notify({
  59. message: options.errorNotitifactionMessage,
  60. type: options.errorNotitifactionType,
  61. })
  62. }
  63. if (options.errorCallback) {
  64. const { graphQLErrors, networkError } = error
  65. let errorHandler: GraphQLHandlerError
  66. if (graphQLErrors.length > 0) {
  67. const { message, extensions }: GraphQLErrorReport = graphQLErrors[0]
  68. errorHandler = {
  69. type:
  70. (extensions?.type as GraphQLErrorTypes) ||
  71. GraphQLErrorTypes.NetworkError,
  72. message,
  73. }
  74. } else if (networkError) {
  75. errorHandler = {
  76. type: GraphQLErrorTypes.NetworkError,
  77. }
  78. } else {
  79. errorHandler = {
  80. type: GraphQLErrorTypes.UnkownError,
  81. }
  82. }
  83. options.errorCallback(errorHandler)
  84. }
  85. }
  86. protected mergedHandlerOptions(
  87. handlerOptions?: CommonHandlerOptionsParameter<THandlerOptions>,
  88. ): CommonHandlerOptions<THandlerOptions> {
  89. // The merged type is always safe as a 'CommonHandlerOptions<THandlerOptions>' type.
  90. return Object.assign(
  91. this.baseHandlerOptions,
  92. handlerOptions,
  93. ) as CommonHandlerOptions<THandlerOptions>
  94. }
  95. }