@@ -18,6 +18,7 @@ import (
1818 "github.com/reearth/reearth/server/internal/usecase/gateway"
1919 "github.com/reearth/reearth/server/pkg/file"
2020 "github.com/reearth/reearth/server/pkg/id"
21+ "github.com/reearth/reearth/server/pkg/visualizer"
2122 "github.com/reearth/reearthx/log"
2223 "github.com/reearth/reearthx/rerror"
2324 "github.com/spf13/afero"
@@ -33,14 +34,14 @@ const (
3334)
3435
3536type fileRepo struct {
36- isTest bool
37+ isFake bool
3738 bucketName string
3839 base * url.URL
3940 cacheControl string
4041 baseFileStorage * infrastructure.BaseFileStorage
4142}
4243
43- func NewFile (isTest bool , bucketName , base string , cacheControl string ) (gateway.File , error ) {
44+ func NewFile (isFake bool , bucketName , base string , cacheControl string ) (gateway.File , error ) {
4445 if bucketName == "" {
4546 return nil , errors .New ("bucket name is empty" )
4647 }
@@ -57,7 +58,7 @@ func NewFile(isTest bool, bucketName, base string, cacheControl string) (gateway
5758 }
5859
5960 return & fileRepo {
60- isTest : isTest ,
61+ isFake : isFake ,
6162 bucketName : bucketName ,
6263 base : u ,
6364 cacheControl : cacheControl ,
@@ -301,7 +302,7 @@ func (f *fileRepo) bucket(ctx context.Context) (*storage.BucketHandle, error) {
301302 var client * storage.Client
302303 var err error
303304
304- if f .isTest {
305+ if f .isFake {
305306 testGCS , err := testutil .NewGCSForTesting ()
306307 if err != nil {
307308 return nil , err
@@ -326,22 +327,53 @@ func (f *fileRepo) bucket(ctx context.Context) (*storage.BucketHandle, error) {
326327
327328func (f * fileRepo ) read (ctx context.Context , filename string ) (io.ReadCloser , error ) {
328329 if filename == "" {
330+ visualizer .WarnWithCallerLogging (ctx , "gcs: read filename is empty" )
329331 return nil , rerror .ErrNotFound
330332 }
331333
332334 bucket , err := f .bucket (ctx )
333335 if err != nil {
334- log .Errorfc (ctx , "gcs: read bucket err: %+v\n " , err )
335- return nil , rerror .ErrInternalByWithContext (ctx , err )
336+ return nil , visualizer .ErrorWithCallerLogging (ctx , "gcs: read bucket err" , rerror .ErrInternalByWithContext (ctx , err ))
337+ }
338+
339+ _ , err = bucket .Object (filename ).Attrs (ctx )
340+ if err != nil && errors .Is (err , storage .ErrObjectNotExist ) {
341+ visualizer .WarnWithCallerLogging (ctx , "gcs: read attrs err" )
342+ return nil , rerror .ErrNotFound
343+ }
344+
345+ if err != nil {
346+ return nil , visualizer .ErrorWithCallerLogging (ctx , "gcs: read attrs err" , rerror .ErrInternalByWithContext (ctx , err ))
347+ }
348+
349+ // Note:
350+ // fsouza/fake-gcs-server can't read object by Reader.
351+ // so we need to download it from the server directly.
352+ if f .isFake {
353+ u := fmt .Sprintf ("http://%s/download/storage/v1/b/%s/o/%s?alt=media" ,
354+ strings .TrimRight ("localhost:4443" , "/" ),
355+ url .PathEscape (bucket .BucketName ()),
356+ url .PathEscape (filename ),
357+ )
358+
359+ resp , err := http .Get (u )
360+ if err != nil {
361+ return nil , err
362+ }
363+
364+ if resp .StatusCode != http .StatusOK {
365+ body , _ := io .ReadAll (resp .Body )
366+ return nil , visualizer .ErrorWithCallerLogging (ctx , "gcs: read fake object err" , fmt .Errorf ("emu GET failed: status=%d body=%s" , resp .StatusCode , string (body )))
367+ }
368+ return resp .Body , nil
336369 }
337370
338371 reader , err := bucket .Object (filename ).NewReader (ctx )
339372 if err != nil {
340373 if errors .Is (err , storage .ErrObjectNotExist ) {
341374 return nil , rerror .ErrNotFound
342375 }
343- log .Errorfc (ctx , "gcs: read err: %+v\n " , err )
344- return nil , rerror .ErrInternalByWithContext (ctx , err )
376+ return nil , visualizer .ErrorWithCallerLogging (ctx , "gcs: read object err" , rerror .ErrInternalByWithContext (ctx , err ))
345377 }
346378
347379 return reader , nil
0 commit comments