Angular Zoneless detect external code changes

Discussão em 'Angular' iniciado por kibet, Janeiro 27, 2025.

  1. kibet

    kibet Guest

    I am using a global error handler and a Graphql provider that handles all requests and errors. However, when throwing an error, it is not caught by the global handler as it is outside it's angular. Throwing an error inside a component works though.

    I'm not using ZoneJs.

    Here is my Graphql provider code:

    import { Apollo, APOLLO_OPTIONS } from 'apollo-angular';
    import { HttpLink } from 'apollo-angular/http';
    import { ApplicationConfig, inject } from '@angular/core';
    import { ApolloClientOptions, InMemoryCache, split } from '@apollo/client/core';
    import { environment } from '../environments/environment';
    import { onError } from '@apollo/client/link/error';
    import { Router } from '@angular/router';
    import { HttpHeaders } from '@angular/common/http';
    import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
    import { getMainDefinition } from '@apollo/client/utilities';
    import { createClient } from 'graphql-ws';

    // @ts-ignore
    import extractFiles from 'extract-files/extractFiles.mjs';
    // @ts-ignore
    import isExtractableFile from 'extract-files/isExtractableFile.mjs';

    const uri = `${environment.base}/graphql`

    export function apolloOptionsFactory(): ApolloClientOptions<any> {
    const httpLink = inject(HttpLink);
    const router = inject(Router)

    const wsLink = new GraphQLWsLink(
    createClient({
    url: (environment.base).toString()
    })
    )

    const errorLink = onError(({ graphQLErrors, networkError }) => {

    if (graphQLErrors) {
    graphQLErrors.forEach(e => {
    if (e.message === 'Unauthorized')
    router.navigate(['auth/login'])
    throw new Error(e.message)
    })
    }

    if (networkError) {
    throw new Error(networkError.message)
    }
    })

    return {
    link: split(
    ({ query }) => {
    const definition = getMainDefinition(query);
    return (
    definition.kind === 'OperationDefinition' &&
    definition.operation === 'subscription'
    )
    },
    wsLink,
    errorLink.concat(httpLink.create({
    uri,
    extractFiles: (body) => extractFiles(body, isExtractableFile),
    headers: new HttpHeaders({ 'x-apollo-operation-name': 'some-header-with-file-upload'})
    }))
    ),
    cache: new InMemoryCache()
    }
    }

    export const graphqlProvider: ApplicationConfig['providers'] = [
    Apollo,
    {
    provide: APOLLO_OPTIONS,
    useFactory: apolloOptionsFactory,
    },
    ];


    Error handling service

    import { ErrorHandler, Injectable, Injector, inject } from "@angular/core";
    import { HttpErrorResponse } from "@angular/common/http";
    import { ErrorService } from "./error.service";
    import { NotificationService } from "./notification.service";

    @Injectable()
    export class GlobalErrorHandler implements ErrorHandler {

    injector: Injector = inject(Injector)

    handleError(error: Error | HttpErrorResponse): void {
    console.log('SOMETHING SHOULD HAPPEN SINCE ALL ERRORS ARE HANDLED HERE')
    const errorService = this.injector.get(ErrorService)
    const notifier = this.injector.get(NotificationService)

    let message: string

    message = errorService.getClientErrorMessage(error)
    notifier.showError(message)
    }
    }


    Graphql methods service

    export class GraphqlService {

    public postsQuery!: QueryRef<any>
    private readonly apollo = inject(Apollo)

    public mutateFn(mutation: TypedDocumentNode<unknown, any>, variables?: any, isFile: boolean = false): Observable<MutationResult<unknown> | any> {
    return this.apollo.mutate({
    mutation: mutation,
    variables: variables,
    errorPolicy: 'all',
    context: {
    useMultipart: isFile
    }
    }).pipe(map((v) => {
    return v.data
    })
    )
    }


    I've tried using ApplicationRef.tick() but I'm getting an error ApplicationRef.tick() is running recursively

    Is there a better way to do this?

    Continue reading...

Compartilhe esta Página