Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/components/primitive-components/Group/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,16 @@ export class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
return traces.length > 0
}

_markAsyncAutoroutingFailedAsSettled() {
// A routing failure should not block later PCB phases like placement DRC.
// Treat the subcircuit as settled with no routed traces and re-run PCB
// trace/render-dependent phases to surface any non-routing errors.
this._asyncAutoroutingResult = {
output_pcb_traces: [],
}
this._markDirty("PcbTraceRender")
}

async _runEffectMakeHttpAutoroutingRequest() {
const { db } = this.root!
const debug = Debug("tscircuit:core:_runEffectMakeHttpAutoroutingRequest")
Expand Down Expand Up @@ -540,6 +550,7 @@ export class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
error_type: "pcb_autorouting_error",
message: err.message,
})
this._markAsyncAutoroutingFailedAsSettled()
throw err
}

Expand Down Expand Up @@ -706,6 +717,8 @@ export class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
message: error instanceof Error ? error.message : String(error),
})

this._markAsyncAutoroutingFailedAsSettled()

this.root?.emit("autorouting:error", {
subcircuit_id: this.subcircuit_id,
componentDisplayName: this.getString(),
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions tests/drc/pcb-hole-overlap-with-autorouting-error.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { test, expect } from "bun:test"
import { createBasicAutorouter } from "../fixtures/createBasicAutorouter"
import { getTestFixture } from "../fixtures/get-test-fixture"

test("design rule check detects pad and hole overlap even after autorouting error", async () => {
const { circuit } = getTestFixture()

circuit.add(
<board
width="80mm"
height="60mm"
autorouter={{
algorithmFn: createBasicAutorouter(async () => {
throw new Error("boom")
}),
}}
>
<capacitor
name="C13"
capacitance="47uF"
footprint="1206"
pcbX={-16.5}
pcbY={-20.5}
connections={{ pin1: "net.V5", pin2: "net.GND" }}
/>
<hole name="H1" diameter="3.2mm" pcbX={-18.5} pcbY={-22.5} />

<resistor
name="R1"
footprint="0402"
resistance="1k"
pcbX={0}
pcbY={0}
/>
<resistor
name="R2"
footprint="0402"
resistance="1k"
pcbX={10}
pcbY={0}
/>
<trace from=".R1 > .pin1" to=".R2 > .pin2" />
</board>,
)

await circuit.renderUntilSettled()

const circuitJson = circuit.getCircuitJson()

const autoroutingErrors = circuitJson.filter(
(el) => el.type === "pcb_autorouting_error",
)
expect(autoroutingErrors).toHaveLength(1)

await expect(circuit).toMatchPcbSnapshot(import.meta.path, {
shouldDrawErrors: true,
})

const insertedOverlapErrors = circuitJson.filter(
(el) => el.type === "pcb_footprint_overlap_error",
)

expect(insertedOverlapErrors).toHaveLength(1)
})
Loading