@@ -99,8 +99,9 @@ func apiError(ctx *context.Context, status int, err error) {
9999// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#error-codes
100100func apiErrorDefined (ctx * context.Context , err * namedError ) {
101101 type ContainerError struct {
102- Code string `json:"code"`
103- Message string `json:"message"`
102+ Code string `json:"code"`
103+ Message string `json:"message"`
104+ Detail interface {} `json:"detail,omitempty"`
104105 }
105106
106107 type ContainerErrors struct {
@@ -112,6 +113,7 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
112113 {
113114 Code : err .Code ,
114115 Message : err .Message ,
116+ Detail : err .Detail ,
115117 },
116118 },
117119 })
@@ -174,7 +176,7 @@ func Authenticate(ctx *context.Context) {
174176
175177 token , err := packages_service .CreateAuthorizationToken (u , packageScope )
176178 if err != nil {
177- apiError (ctx , http . StatusInternalServerError , err )
179+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
178180 return
179181 }
180182
@@ -204,7 +206,7 @@ func GetRepositoryList(ctx *context.Context) {
204206
205207 repositories , err := container_model .GetRepositories (ctx , ctx .Doer , n , last )
206208 if err != nil {
207- apiError (ctx , http . StatusInternalServerError , err )
209+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
208210 return
209211 }
210212
@@ -243,13 +245,13 @@ func InitiateUploadBlob(ctx *context.Context) {
243245 if blob != nil {
244246 accessible , err := packages_model .IsBlobAccessibleForUser (ctx , blob .Blob .ID , ctx .Doer )
245247 if err != nil {
246- apiError (ctx , http . StatusInternalServerError , err )
248+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
247249 return
248250 }
249251
250252 if accessible {
251253 if err := mountBlob (ctx , & packages_service.PackageInfo {Owner : ctx .Package .Owner , Name : image }, blob .Blob ); err != nil {
252- apiError (ctx , http . StatusInternalServerError , err )
254+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
253255 return
254256 }
255257
@@ -267,7 +269,7 @@ func InitiateUploadBlob(ctx *context.Context) {
267269 if digest != "" {
268270 buf , err := packages_module .CreateHashedBufferFromReader (ctx .Req .Body )
269271 if err != nil {
270- apiError (ctx , http . StatusInternalServerError , err )
272+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
271273 return
272274 }
273275 defer buf .Close ()
@@ -291,7 +293,7 @@ func InitiateUploadBlob(ctx *context.Context) {
291293 case packages_service .ErrQuotaTotalCount , packages_service .ErrQuotaTypeSize , packages_service .ErrQuotaTotalSize :
292294 apiError (ctx , http .StatusForbidden , err )
293295 default :
294- apiError (ctx , http . StatusInternalServerError , err )
296+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
295297 }
296298 return
297299 }
@@ -306,7 +308,7 @@ func InitiateUploadBlob(ctx *context.Context) {
306308
307309 upload , err := packages_model .CreateBlobUpload (ctx )
308310 if err != nil {
309- apiError (ctx , http . StatusInternalServerError , err )
311+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
310312 return
311313 }
312314
@@ -327,7 +329,7 @@ func GetUploadBlob(ctx *context.Context) {
327329 if err == packages_model .ErrPackageBlobUploadNotExist {
328330 apiErrorDefined (ctx , errBlobUploadUnknown )
329331 } else {
330- apiError (ctx , http . StatusInternalServerError , err )
332+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
331333 }
332334 return
333335 }
@@ -348,7 +350,7 @@ func UploadBlob(ctx *context.Context) {
348350 if err == packages_model .ErrPackageBlobUploadNotExist {
349351 apiErrorDefined (ctx , errBlobUploadUnknown )
350352 } else {
351- apiError (ctx , http . StatusInternalServerError , err )
353+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
352354 }
353355 return
354356 }
@@ -367,12 +369,12 @@ func UploadBlob(ctx *context.Context) {
367369 return
368370 }
369371 } else if uploader .Size () != 0 {
370- apiErrorDefined (ctx , errBlobUploadInvalid .WithMessage ("Stream uploads after first write are not allowed" ))
372+ apiErrorDefined (ctx , errBlobUploadInvalid .WithDetail ("Stream uploads after first write are not allowed" ))
371373 return
372374 }
373375
374376 if err := uploader .Append (ctx , ctx .Req .Body ); err != nil {
375- apiError (ctx , http . StatusInternalServerError , err )
377+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
376378 return
377379 }
378380
@@ -399,7 +401,7 @@ func EndUploadBlob(ctx *context.Context) {
399401 if err == packages_model .ErrPackageBlobUploadNotExist {
400402 apiErrorDefined (ctx , errBlobUploadUnknown )
401403 } else {
402- apiError (ctx , http . StatusInternalServerError , err )
404+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
403405 }
404406 return
405407 }
@@ -412,7 +414,7 @@ func EndUploadBlob(ctx *context.Context) {
412414
413415 if ctx .Req .Body != nil {
414416 if err := uploader .Append (ctx , ctx .Req .Body ); err != nil {
415- apiError (ctx , http . StatusInternalServerError , err )
417+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
416418 return
417419 }
418420 }
@@ -436,19 +438,19 @@ func EndUploadBlob(ctx *context.Context) {
436438 case packages_service .ErrQuotaTotalCount , packages_service .ErrQuotaTypeSize , packages_service .ErrQuotaTotalSize :
437439 apiError (ctx , http .StatusForbidden , err )
438440 default :
439- apiError (ctx , http . StatusInternalServerError , err )
441+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
440442 }
441443 return
442444 }
443445
444446 if err := uploader .Close (); err != nil {
445- apiError (ctx , http . StatusInternalServerError , err )
447+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
446448 return
447449 }
448450 doClose = false
449451
450452 if err := container_service .RemoveBlobUploadByID (ctx , uploader .ID ); err != nil {
451- apiError (ctx , http . StatusInternalServerError , err )
453+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
452454 return
453455 }
454456
@@ -468,13 +470,13 @@ func CancelUploadBlob(ctx *context.Context) {
468470 if err == packages_model .ErrPackageBlobUploadNotExist {
469471 apiErrorDefined (ctx , errBlobUploadUnknown )
470472 } else {
471- apiError (ctx , http . StatusInternalServerError , err )
473+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
472474 }
473475 return
474476 }
475477
476478 if err := container_service .RemoveBlobUploadByID (ctx , uuid ); err != nil {
477- apiError (ctx , http . StatusInternalServerError , err )
479+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
478480 return
479481 }
480482
@@ -504,7 +506,7 @@ func HeadBlob(ctx *context.Context) {
504506 if err == container_model .ErrContainerBlobNotExist {
505507 apiErrorDefined (ctx , errBlobUnknown )
506508 } else {
507- apiError (ctx , http . StatusInternalServerError , err )
509+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
508510 }
509511 return
510512 }
@@ -523,7 +525,7 @@ func GetBlob(ctx *context.Context) {
523525 if err == container_model .ErrContainerBlobNotExist {
524526 apiErrorDefined (ctx , errBlobUnknown )
525527 } else {
526- apiError (ctx , http . StatusInternalServerError , err )
528+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
527529 }
528530 return
529531 }
@@ -541,7 +543,7 @@ func DeleteBlob(ctx *context.Context) {
541543 }
542544
543545 if err := deleteBlob (ctx , ctx .Package .Owner .ID , ctx .PathParam ("image" ), d ); err != nil {
544- apiError (ctx , http . StatusInternalServerError , err )
546+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
545547 return
546548 }
547549
@@ -564,20 +566,20 @@ func UploadManifest(ctx *context.Context) {
564566 }
565567
566568 if mci .IsTagged && ! referencePattern .MatchString (reference ) {
567- apiErrorDefined (ctx , errManifestInvalid . WithMessage ( "Tag is invalid" ) )
569+ apiErrorDefined (ctx , errTagInvalid )
568570 return
569571 }
570572
571573 maxSize := maxManifestSize + 1
572574 buf , err := packages_module .CreateHashedBufferFromReaderWithSize (& io.LimitedReader {R : ctx .Req .Body , N : int64 (maxSize )}, maxSize )
573575 if err != nil {
574- apiError (ctx , http . StatusInternalServerError , err )
576+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
575577 return
576578 }
577579 defer buf .Close ()
578580
579581 if buf .Size () > maxManifestSize {
580- apiErrorDefined (ctx , errManifestInvalid .WithMessage ("Manifest exceeds maximum size" ).WithStatusCode (http .StatusRequestEntityTooLarge ))
582+ apiErrorDefined (ctx , errManifestInvalid .WithDetail ("Manifest exceeds maximum size" ).WithStatusCode (http .StatusRequestEntityTooLarge ))
581583 return
582584 }
583585
@@ -593,7 +595,7 @@ func UploadManifest(ctx *context.Context) {
593595 case packages_service .ErrQuotaTotalCount , packages_service .ErrQuotaTypeSize , packages_service .ErrQuotaTotalSize :
594596 apiError (ctx , http .StatusForbidden , err )
595597 default :
596- apiError (ctx , http . StatusInternalServerError , err )
598+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
597599 }
598600 }
599601 return
@@ -642,7 +644,7 @@ func HeadManifest(ctx *context.Context) {
642644 if err == container_model .ErrContainerBlobNotExist {
643645 apiErrorDefined (ctx , errManifestUnknown )
644646 } else {
645- apiError (ctx , http . StatusInternalServerError , err )
647+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
646648 }
647649 return
648650 }
@@ -662,7 +664,7 @@ func GetManifest(ctx *context.Context) {
662664 if err == container_model .ErrContainerBlobNotExist {
663665 apiErrorDefined (ctx , errManifestUnknown )
664666 } else {
665- apiError (ctx , http . StatusInternalServerError , err )
667+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
666668 }
667669 return
668670 }
@@ -681,7 +683,7 @@ func DeleteManifest(ctx *context.Context) {
681683
682684 pvs , err := container_model .GetManifestVersions (ctx , opts )
683685 if err != nil {
684- apiError (ctx , http . StatusInternalServerError , err )
686+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
685687 return
686688 }
687689
@@ -692,7 +694,7 @@ func DeleteManifest(ctx *context.Context) {
692694
693695 for _ , pv := range pvs {
694696 if err := packages_service .RemovePackageVersion (ctx , ctx .Doer , pv ); err != nil {
695- apiError (ctx , http . StatusInternalServerError , err )
697+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
696698 return
697699 }
698700 }
@@ -707,7 +709,7 @@ func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor)
707709 serveDirectReqParams .Set ("response-content-type" , pfd .Properties .GetByName (container_module .PropertyMediaType ))
708710 s , u , _ , err := packages_service .GetPackageBlobStream (ctx , pfd .File , pfd .Blob , serveDirectReqParams )
709711 if err != nil {
710- apiError (ctx , http . StatusInternalServerError , err )
712+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
711713 return
712714 }
713715
@@ -742,7 +744,7 @@ func GetTagList(ctx *context.Context) {
742744 if err == packages_model .ErrPackageNotExist {
743745 apiErrorDefined (ctx , errNameUnknown )
744746 } else {
745- apiError (ctx , http . StatusInternalServerError , err )
747+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
746748 }
747749 return
748750 }
@@ -755,7 +757,7 @@ func GetTagList(ctx *context.Context) {
755757
756758 tags , err := container_model .GetImageTags (ctx , ctx .Package .Owner .ID , image , n , last )
757759 if err != nil {
758- apiError (ctx , http . StatusInternalServerError , err )
760+ apiErrorDefined (ctx , errUnsupported . WithDetail ( err ) )
759761 return
760762 }
761763
0 commit comments