11"use server" ;
22
3- import { GetObjectCommand , S3Client } from "@aws-sdk/client-s3" ;
3+ import { GetObjectCommand , S3Client , S3ServiceException } from "@aws-sdk/client-s3" ;
44import { VaccineTypes } from "@src/models/vaccine" ;
55import { VaccineContentPaths , vaccineTypeToPath } from "@src/services/content-api/constants" ;
66import { getFilteredContentForVaccine } from "@src/services/content-api/parsers/content-filter-service" ;
99 ContentErrorTypes ,
1010 GetContentForVaccineResponse ,
1111 StyledVaccineContent ,
12- VaccinePageContent ,
12+ VaccinePageContent
1313} from "@src/services/content-api/types" ;
1414import { AppConfig , configProvider } from "@src/utils/config" ;
1515import { AWS_PRIMARY_REGION } from "@src/utils/constants" ;
@@ -18,18 +18,24 @@ import { S3_PREFIX, isS3Path } from "@src/utils/path";
1818import { readFile } from "node:fs/promises" ;
1919import { Logger } from "pino" ;
2020import { Readable } from "stream" ;
21+ import {
22+ ReadingS3Error ,
23+ S3NoSuchKeyError ,
24+ S3HttpStatusError ,
25+ } from "@src/services/content-api/gateway/exceptions" ;
26+ import { HttpStatusCode } from "axios" ;
2127
2228const log : Logger = logger . child ( { module : "content-reader-service" } ) ;
2329
2430const _readFileS3 = async ( bucket : string , key : string ) : Promise < string > => {
2531 try {
2632 const s3Client : S3Client = new S3Client ( {
27- region : AWS_PRIMARY_REGION ,
33+ region : AWS_PRIMARY_REGION
2834 } ) ;
2935
3036 const getObjectCommand : GetObjectCommand = new GetObjectCommand ( {
3137 Bucket : bucket ,
32- Key : key ,
38+ Key : key
3339 } ) ;
3440 const { Body } = await s3Client . send ( getObjectCommand ) ;
3541
@@ -41,24 +47,33 @@ const _readFileS3 = async (bucket: string, key: string): Promise<string> => {
4147 Body . on ( "error" , reject ) ;
4248 } ) ;
4349 }
44- } catch ( error ) {
45- log . error ( `Error reading file from S3: ${ error } ` ) ;
46- throw error ;
47- }
50+ } catch ( error : unknown ) {
51+ if ( error instanceof S3ServiceException ) {
52+ if ( error . name === "NoSuchKey" ) {
53+ log . error ( error , `Error in reading Content API from S3: File not found ${ bucket } /${ key } ` ) ;
54+ throw new S3NoSuchKeyError ( `Error in reading Content API from S3` ) ;
55+ }
4856
49- throw new Error ( "Unexpected response type" ) ;
57+ const statusCode = error . $metadata ?. httpStatusCode ;
58+ if ( statusCode && statusCode >= HttpStatusCode . BadRequest ) {
59+ log . error ( error , `Error in reading Content API from S3 ${ bucket } /${ key } ` ) ;
60+ throw new S3HttpStatusError ( `Error in reading Content API from S3` ) ;
61+ }
62+
63+ log . error ( error , `Unhandled error in reading Content API from S3: ${ bucket } /${ key } ` ) ;
64+ throw error ;
65+ }
66+ }
67+ log . error ( "Error fetching content: unexpected response type" ) ;
68+ throw new Error ( "Error fetching content: unexpected response type" ) ;
5069} ;
5170
5271const _readContentFromCache = async ( cacheLocation : string , cachePath : string ) : Promise < string > => {
5372 log . info ( `Reading file from cache: loc=${ cacheLocation } , path=${ cachePath } ` ) ;
54- try {
55- return isS3Path ( cacheLocation )
56- ? await _readFileS3 ( cacheLocation . slice ( S3_PREFIX . length ) , cachePath )
57- : await readFile ( `${ cacheLocation } ${ cachePath } ` , { encoding : "utf8" } ) ;
58- } catch ( error ) {
59- log . error ( `Error reading file from cache: loc=${ cacheLocation } : ${ error } ` ) ;
60- throw error ;
61- }
73+
74+ return isS3Path ( cacheLocation )
75+ ? await _readFileS3 ( cacheLocation . slice ( S3_PREFIX . length ) , cachePath )
76+ : await readFile ( `${ cacheLocation } ${ cachePath } ` , { encoding : "utf8" } ) ;
6277} ;
6378
6479const getContentForVaccine = async ( vaccineType : VaccineTypes ) : Promise < GetContentForVaccineResponse > => {
@@ -77,11 +92,18 @@ const getContentForVaccine = async (vaccineType: VaccineTypes): Promise<GetConte
7792
7893 return { styledVaccineContent, contentError : undefined } ;
7994 } catch ( error ) {
80- log . error ( `Error getting content for vaccine: ${ error } ` ) ;
81- return {
82- styledVaccineContent : undefined ,
83- contentError : ContentErrorTypes . CONTENT_LOADING_ERROR ,
84- } ;
95+ if ( error instanceof ReadingS3Error ) {
96+ return {
97+ styledVaccineContent : undefined ,
98+ contentError : ContentErrorTypes . CONTENT_LOADING_ERROR
99+ } ;
100+ } else {
101+ log . error ( error , `Error getting content for vaccine: ${ vaccineType } ` ) ;
102+ return {
103+ styledVaccineContent : undefined ,
104+ contentError : ContentErrorTypes . CONTENT_LOADING_ERROR
105+ } ;
106+ }
85107 }
86108} ;
87109
0 commit comments