• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / storage / 25398322339

05 May 2026 07:42PM UTC coverage: 74.031% (-0.2%) from 74.256%
25398322339

Pull #922

github

web-flow
Merge abfd0b1f9 into 44260a113
Pull Request #922: fix: no any rule

3969 of 5916 branches covered (67.09%)

Branch coverage included in aggregate %.

102 of 154 new or added lines in 23 files covered. (66.23%)

9 existing lines in 5 files now uncovered.

8004 of 10257 relevant lines covered (78.03%)

406.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

41.33
/src/http/routes/s3/error-handler.ts
1
import { S3ServiceException } from '@aws-sdk/client-s3'
2
import { FastifyError } from '@fastify/error'
3
import { ErrorCode, StorageBackendError } from '@internal/errors'
4
import { FastifyReply } from 'fastify/types/reply'
5
import { FastifyRequest } from 'fastify/types/request'
6
import { DatabaseError } from 'pg'
7

8
type ValidationIssue = {
9
  instancePath?: string
10
  message?: string
11
}
12

13
export const s3ErrorHandler = (
27✔
14
  error: FastifyError | Error,
15
  request: FastifyRequest,
16
  reply: FastifyReply
17
) => {
18
  request.executionError = error
23✔
19
  const validation = getValidationIssues(error)
23✔
20

21
  const resource = request.url
23✔
22
    .split('?')[0]
23
    .replace('/s3', '')
24
    .split('/')
25
    .filter((e) => e)
72✔
26
    .join('/')
27

28
  if (validation) {
23!
29
    return reply.status(400).send({
×
30
      Error: {
31
        Resource: resource,
32
        Code: ErrorCode.InvalidRequest,
33
        Message: formatValidationError(validation).message,
34
      },
35
    })
36
  }
37

38
  if (error instanceof S3ServiceException) {
23!
39
    return reply.status(error.$metadata.httpStatusCode || 500).send({
×
40
      Error: {
41
        Resource: resource,
42
        Code: error.$response?.body.Code || ErrorCode.S3Error,
×
43
        Message: error.message,
44
      },
45
    })
46
  }
47

48
  // database error
49
  if (
23!
50
    error instanceof DatabaseError &&
23!
51
    [
52
      'Max client connections reached',
53
      'remaining connection slots are reserved for non-replication superuser connections',
54
      'no more connections allowed',
55
      'sorry, too many clients already',
56
      'server login has been failing, try again later',
57
    ].some((msg) => (error as DatabaseError).message.includes(msg))
×
58
  ) {
59
    return reply.status(429).send({
×
60
      Error: {
61
        Resource: resource,
62
        Code: ErrorCode.SlowDown,
63
        Message: 'Too many connections issued to the database',
64
      },
65
    })
66
  }
67

68
  if (error instanceof StorageBackendError) {
23✔
69
    return reply.status(error.httpStatusCode || 500).send({
21!
70
      Error: {
71
        Resource: resource,
72
        Code: error.code,
73
        Message: error.message,
74
      },
75
    })
76
  }
77

78
  const statusCode =
79
    'statusCode' in error && typeof error.statusCode === 'number' ? error.statusCode : undefined
2!
80

81
  if (statusCode && statusCode >= 400 && statusCode < 500) {
23✔
82
    return reply.status(statusCode).send({
2✔
83
      Error: {
84
        Resource: resource,
85
        Code: ErrorCode.InvalidRequest,
86
        Message: error.message,
87
      },
88
    })
89
  }
90

91
  return reply.status(500).send({
×
92
    Error: {
93
      Resource: resource,
94
      Code: ErrorCode.InternalError,
95
      Message: 'Internal Server Error',
96
    },
97
  })
98
}
99

100
function isValidationIssueArray(value: unknown): value is ValidationIssue[] {
NEW
101
  return Array.isArray(value) && value.every(isValidationIssue)
×
102
}
103

104
function isValidationIssue(value: unknown): value is ValidationIssue {
NEW
105
  if (!value || typeof value !== 'object') {
×
NEW
106
    return false
×
107
  }
108

NEW
109
  const issue = value as ValidationIssue
×
NEW
110
  return (
×
111
    (issue.instancePath === undefined || typeof issue.instancePath === 'string') &&
112
    (issue.message === undefined || typeof issue.message === 'string')
113
  )
114
}
115

116
function getValidationIssues(error: FastifyError | Error): ValidationIssue[] | undefined {
117
  if (!('validation' in error)) {
23!
118
    return undefined
23✔
119
  }
120

NEW
121
  const value = error.validation
×
NEW
122
  return isValidationIssueArray(value) ? value : undefined
×
123
}
124

125
function formatValidationError(errors: readonly ValidationIssue[]) {
126
  let text = ''
×
127
  const separator = ', '
×
128

129
  for (let i = 0; i !== errors.length; ++i) {
×
130
    const e = errors[i]
×
131
    const instancePath = (e.instancePath || '').replace(/^\//, '')
×
132
    text += instancePath.split('/').join(separator) + ' ' + e.message + separator
×
133
  }
134
  return new Error(text.slice(0, -separator.length))
×
135
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc