I'm trying Amplify to host my Angular app.. When I build this locally it works (of course) - but for some reason it can't find my AuthInterceptor. 2025-04-07T01:51:44.297Z [INFO]: Prerendered 0 static routes. Application bundle generation failed. [13.660 seconds] 2025-04-07T01:51:44.301Z [WARNING]: ✘ [ERROR] TS2307: Cannot find module './interceptor/AuthInterceptor' or its corresponding type declarations. [plugin angular-compiler] src/app/app.config.ts:8:32: 8 │ import { AuthInterceptor } from './interceptor/AuthInterceptor'; ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ✘ [ERROR] Could not resolve "./app/interceptor/AuthInterceptor" src/main.ts:7:32: 7 │ import { AuthInterceptor } from './app/interceptor/AuthInterceptor'; ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ✘ [ERROR] TS2307: Cannot find module './app/interceptor/AuthInterceptor' or its corresponding type declarations. [plugin angular-compiler] src/main.ts:7:32: 7 │ import { AuthInterceptor } from './app/interceptor/AuthInterceptor'; ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2025-04-07T01:51:44.420Z [ERROR]: !!! Build failed this is the amplify.yml: version: 1 applications: - appRoot: "APP_UI/src" frontend: phases: preBuild: commands: - nvm install 20.17.0 - nvm use 20.17.0 - npm install -g npm@11.0.0 - npm ci --cache .npm --prefer-offline build: commands: - npm run build artifacts: baseDirectory: dist/app files: - '**/*' cache: paths: - .npm/**/* tsconfig.json: { "compileOnSave": false, "compilerOptions": { "outDir": "./dist/app", "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "esModuleInterop": true, "strictPropertyInitialization": false, "sourceMap": true, "declaration": false, "experimentalDecorators": true, "emitDecoratorMetadata": true, "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": [ "ES2022", "dom" ], "baseUrl": "./src", "paths": { "@app/*": ["app/*"] } }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true, "skipTemplateCodegen": true }, "include": ["src/**/*"] } AuthInterceptor.ts (UI\src\app\interceptor): import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError, of } from 'rxjs'; import { catchError, retry, delay, switchMap } from 'rxjs/operators'; import { ModalService } from '../services/modal.service'; import { Router } from '@angular/router'; import { MatSnackBar } from '@angular/material/snack-bar'; import { LoginService } from '../services/loginService'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor( private modalService: ModalService, private router: Router, private snackBar: MatSnackBar, private loginService: LoginService ) {} intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const token = localStorage.getItem('authToken'); const cloned = token ? req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) }) : req; return next.handle(cloned).pipe( retry({ delay: (retryCount) => of(retryCount).pipe(delay(retryCount * 1000)), // Incremental delay count: 3 // Retry 3 times }), catchError((error: HttpErrorResponse) => { if (error.status === 401) { // Avoid looping if already on authentication route if (this.router.url !== '/register') { this.snackBar.open('Credentials Incorrect or Session Expired. Please log in again.', 'OK', { duration: 3000 }); return this.loginService.refreshToken().pipe( switchMap((newToken: string) => { localStorage.setItem('authToken', newToken); const newRequest = req.clone({ setHeaders: { Authorization: `Bearer ${newToken}` } }); return next.handle(newRequest); }), catchError(refreshError => { setTimeout(() => { this.router.navigate(['/login']); }, 3000); // Delay navigation to allow snackBar display return throwError(refreshError); }) ); } } else if (error.status >= 500) { this.snackBar.open('Server error. Redirecting...', 'OK', { duration: 3000 }); setTimeout(() => { this.router.navigate(['/error']); }, 3000); // Delay navigation to allow snackBar display } else if (!navigator.onLine) { this.snackBar.open('No internet connection. Redirecting...', 'OK', { duration: 3000 }); setTimeout(() => { this.router.navigate(['/error']); }, 3000); // Delay navigation to allow snackBar display } else if (error.status >= 400 && error.status < 500) { this.modalService.openModal(); // Use modal service only for client errors } else { this.snackBar.open('An unexpected error occurred. Please try again.', 'OK', { duration: 3000 }); setTimeout(() => { this.router.navigate(['/error']); }, 3000); // Delay navigation to allow snackBar display } return throwError(() => new Error(error.message)); // Updated to new throwError syntax }) ); } } main.ts: import { importProvidersFrom } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { provideHttpClient, HTTP_INTERCEPTORS, withInterceptorsFromDi } from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app/app.component'; import { AuthInterceptor } from './app/interceptor/AuthInterceptor'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { routes } from './app/app.routes'; import { LoggerService } from './app/services/logger.service'; bootstrapApplication(AppComponent, { providers: [ importProvidersFrom(MatSnackBarModule, BrowserAnimationsModule, RouterModule.forRoot(routes)), provideHttpClient(withInterceptorsFromDi()), { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, LoggerService ] }); app.config: import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { CommonModule } from '@angular/common'; import { AuthInterceptor } from './interceptor/AuthInterceptor'; import { AuthService } from './services/authService'; import { AuthGuard } from './guards/AuthGuard'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), AuthService, AuthGuard, provideClientHydration(), provideAnimationsAsync(), importProvidersFrom(HttpClientModule, CommonModule), { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }; I can provide whatever else you need but I don't know what else to provide. Continue reading...