From 65349e4fa2b1d7169dc9a738ba9c819c7fe734a6 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Thu, 19 Mar 2026 18:48:24 -0500 Subject: [PATCH] mock API: invalidRequest helper --- mock-api/msw/db.ts | 12 +++------- mock-api/msw/handlers.ts | 49 ++++++++++------------------------------ mock-api/msw/util.ts | 3 +++ 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/mock-api/msw/db.ts b/mock-api/msw/db.ts index 398868e27..e8679f897 100644 --- a/mock-api/msw/db.ts +++ b/mock-api/msw/db.ts @@ -20,7 +20,7 @@ import { commaSeries } from '~/util/str' import type { Json } from '../json-type' import { projects, type DbProject } from '../project' import { defaultSilo, siloSettings } from '../silo' -import { internalError } from './util' +import { internalError, invalidRequest } from './util' export const notFoundErr = (msg: string) => { const message = `not found: ${msg}` @@ -52,7 +52,7 @@ function ensureNoParentSelectors( .map(([k]) => k) if (keysWithValues.length > 0) { const message = `when ${resourceLabel} is specified by ID, ${commaSeries(keysWithValues, 'and')} should not be specified` - throw json({ error_code: 'InvalidRequest', message }, { status: 400 }) + throw invalidRequest(message) } } @@ -101,13 +101,7 @@ export const resolvePoolSelector = ( !poolSelector.ip_version && candidateLinks.length > 1 ) { - throw json( - { - error_code: 'InvalidRequest', - message: 'ip_version required when multiple default pools exist', - }, - { status: 400 } - ) + throw invalidRequest('ip_version required when multiple default pools exist') } const link = candidateLinks[0] diff --git a/mock-api/msw/handlers.ts b/mock-api/msw/handlers.ts index c48e9768b..cc564ee2f 100644 --- a/mock-api/msw/handlers.ts +++ b/mock-api/msw/handlers.ts @@ -55,6 +55,7 @@ import { getBlockSize, handleMetrics, handleOxqlMetrics, + invalidRequest, ipRangeLen, NotImplemented, paginated, @@ -558,21 +559,13 @@ export const handlers = makeHandlers({ // Based on Omicron validation in nexus/db-queries/src/db/datastore/external_ip.rs:544-661 const ipVersion = pool.ip_version if (ipVersion === 'v4' && !hasIpv4Nic) { - throw json( - { - error_code: 'InvalidRequest', - message: `The ephemeral external IP is an IPv4 address, but the instance with ID ${body.name} does not have a primary network interface with a VPC-private IPv4 address. Add a VPC-private IPv4 address to the interface, or attach a different IP address`, - }, - { status: 400 } + throw invalidRequest( + `The ephemeral external IP is an IPv4 address, but the instance with ID ${body.name} does not have a primary network interface with a VPC-private IPv4 address. Add a VPC-private IPv4 address to the interface, or attach a different IP address` ) } if (ipVersion === 'v6' && !hasIpv6Nic) { - throw json( - { - error_code: 'InvalidRequest', - message: `The ephemeral external IP is an IPv6 address, but the instance with ID ${body.name} does not have a primary network interface with a VPC-private IPv6 address. Add a VPC-private IPv6 address to the interface, or attach a different IP address`, - }, - { status: 400 } + throw invalidRequest( + `The ephemeral external IP is an IPv6 address, but the instance with ID ${body.name} does not have a primary network interface with a VPC-private IPv6 address. Add a VPC-private IPv6 address to the interface, or attach a different IP address` ) } } @@ -888,35 +881,21 @@ export const handlers = makeHandlers({ const primaryNic = nics.find((n) => n.primary) if (!primaryNic) { - throw json( - { - error_code: 'InvalidRequest', - message: `Instance ${instance.name} has no primary network interface`, - }, - { status: 400 } - ) + throw invalidRequest(`Instance ${instance.name} has no primary network interface`) } const ipVersion = pool.ip_version const stackType = primaryNic.ip_stack.type if (ipVersion === 'v4' && stackType !== 'v4' && stackType !== 'dual_stack') { - throw json( - { - error_code: 'InvalidRequest', - message: `The ephemeral external IP is an IPv4 address, but the instance with ID ${instance.name} does not have a primary network interface with a VPC-private IPv4 address. Add a VPC-private IPv4 address to the interface, or attach a different IP address`, - }, - { status: 400 } + throw invalidRequest( + `The ephemeral external IP is an IPv4 address, but the instance with ID ${instance.name} does not have a primary network interface with a VPC-private IPv4 address. Add a VPC-private IPv4 address to the interface, or attach a different IP address` ) } if (ipVersion === 'v6' && stackType !== 'v6' && stackType !== 'dual_stack') { - throw json( - { - error_code: 'InvalidRequest', - message: `The ephemeral external IP is an IPv6 address, but the instance with ID ${instance.name} does not have a primary network interface with a VPC-private IPv6 address. Add a VPC-private IPv6 address to the interface, or attach a different IP address`, - }, - { status: 400 } + throw invalidRequest( + `The ephemeral external IP is an IPv6 address, but the instance with ID ${instance.name} does not have a primary network interface with a VPC-private IPv6 address. Add a VPC-private IPv6 address to the interface, or attach a different IP address` ) } @@ -949,12 +928,8 @@ export const handlers = makeHandlers({ ) if (attachedVersions.size > 1 && !ipVersion) { - throw json( - { - error_code: 'InvalidRequest', - message: `Instance ${instance.name} has both IPv4 and IPv6 ephemeral IPs; ipVersion is required to detach one`, - }, - { status: 400 } + throw invalidRequest( + `Instance ${instance.name} has both IPv4 and IPv6 ephemeral IPs; ipVersion is required to detach one` ) } diff --git a/mock-api/msw/util.ts b/mock-api/msw/util.ts index 091a5fde4..13ccecc28 100644 --- a/mock-api/msw/util.ts +++ b/mock-api/msw/util.ts @@ -110,6 +110,9 @@ export const NotImplemented = () => { throw json({ error_code: 'NotImplemented' }, { status: 501 }) } +export const invalidRequest = (message: string) => + json({ error_code: 'InvalidRequest', message }, { status: 400 }) + export const internalError = (message: string) => json({ error_code: 'InternalError', message }, { status: 500 })