[2204] 손상 plan InvalidStateError 3단 방어 (entry/cache/save guard)
This commit is contained in:
parent
8192f0929a
commit
a5e794b3ec
@ -48,6 +48,18 @@ export function useRoofFn() {
|
|||||||
roofMaterial = polygon.roofMaterial ?? selectedRoofMaterial
|
roofMaterial = polygon.roofMaterial ?? selectedRoofMaterial
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [ROOF-PATTERN-GUARD 2026-05-08] polygon bbox 0 또는 roofMaterial 결손 시
|
||||||
|
// 0×0 patternSourceCanvas 가 만들어져 drawImage InvalidStateError 로 페이지 500 진입.
|
||||||
|
// 손상 plan(예 S203X460260507001) 로드 케이스 차단.
|
||||||
|
if (!polygon.width || !polygon.height) {
|
||||||
|
console.warn('[ROOF-PATTERN-GUARD] skip pattern, 0-dim polygon:', polygon.id, polygon.name, polygon.width, polygon.height)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!roofMaterial || !roofMaterial.layout) {
|
||||||
|
console.warn('[ROOF-PATTERN-GUARD] skip pattern, invalid roofMaterial:', polygon.id, roofMaterial)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const ratio = window.devicePixelRatio || 1
|
const ratio = window.devicePixelRatio || 1
|
||||||
const layout = roofMaterial.layout
|
const layout = roofMaterial.layout
|
||||||
|
|
||||||
|
|||||||
@ -139,6 +139,30 @@ export function useCanvas(id) {
|
|||||||
|
|
||||||
const initialize = () => {
|
const initialize = () => {
|
||||||
canvas.getObjects().length > 0 && canvas?.clear()
|
canvas.getObjects().length > 0 && canvas?.clear()
|
||||||
|
// [BG-CACHE-DIAG 2026-05-08] drawCacheOnCanvas 0-dim cache 차단 + 식별
|
||||||
|
// 운영 S203X460260507001 등 손상된 plan 로드 시 InvalidStateError 방지.
|
||||||
|
// 객체 width/height 가 정상이어도 zoom/scale/bbox 조합으로 _cacheCanvas 가
|
||||||
|
// 0×0 이 될 수 있어 객체 단위 가드로는 부족. drawCacheOnCanvas 직전에
|
||||||
|
// 캐시 캔버스 dim 검사 + 로그 + 캐시 비활성으로 차단.
|
||||||
|
if (!fabric.Object.prototype.__bgCacheDiagPatched) {
|
||||||
|
const origDrawCache = fabric.Object.prototype.drawCacheOnCanvas
|
||||||
|
fabric.Object.prototype.drawCacheOnCanvas = function (ctx) {
|
||||||
|
const c = this._cacheCanvas
|
||||||
|
if (!c || !c.width || !c.height) {
|
||||||
|
console.warn('[BG-CACHE-DIAG] skip 0-dim cache:', {
|
||||||
|
type: this.type, name: this.name, id: this.id,
|
||||||
|
w: this.width, h: this.height,
|
||||||
|
sx: this.scaleX, sy: this.scaleY,
|
||||||
|
visible: this.visible, opacity: this.opacity,
|
||||||
|
cacheW: c?.width, cacheH: c?.height,
|
||||||
|
})
|
||||||
|
this.objectCaching = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return origDrawCache.call(this, ctx)
|
||||||
|
}
|
||||||
|
fabric.Object.prototype.__bgCacheDiagPatched = true
|
||||||
|
}
|
||||||
// settings for all canvas in the app
|
// settings for all canvas in the app
|
||||||
fabric.Object.prototype.transparentCorners = false
|
fabric.Object.prototype.transparentCorners = false
|
||||||
fabric.Object.prototype.selectable = true
|
fabric.Object.prototype.selectable = true
|
||||||
|
|||||||
@ -177,6 +177,24 @@ export function usePlan(params = {}) {
|
|||||||
* @param {boolean} saveAlert - 저장 완료 알림 표시 여부
|
* @param {boolean} saveAlert - 저장 완료 알림 표시 여부
|
||||||
*/
|
*/
|
||||||
const saveCanvas = async (saveAlert = true) => {
|
const saveCanvas = async (saveAlert = true) => {
|
||||||
|
// [ROOF-MATERIAL-SAVE-GUARD 2026-05-08] 면(roof) 에 시각적 지붕재 패턴은 칠해져 있는데
|
||||||
|
// 데이터(roofMaterial) 가 비어있는 "불일치" 케이스만 저장 차단.
|
||||||
|
// - fill 비어있고 roofMaterial 도 없음 → 미선택 상태, 저장 허용
|
||||||
|
// - fill 이 fabric.Pattern 인데 roofMaterial 누락 → 저장 시 누락 JSON 이 DB 로 가고
|
||||||
|
// 재로드 시 setSurfaceShapePattern 0×0 patternCanvas → drawImage InvalidStateError
|
||||||
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.wall)
|
||||||
|
const inconsistent = roofs.filter((r) => {
|
||||||
|
const f = r.fill
|
||||||
|
const hasPatternFill = f && typeof f === 'object' && (f.source || f.type === 'pattern')
|
||||||
|
return hasPatternFill && !r.roofMaterial
|
||||||
|
})
|
||||||
|
if (inconsistent.length > 0) {
|
||||||
|
console.warn('[ROOF-MATERIAL-SAVE-GUARD] pattern drawn but roofMaterial missing:',
|
||||||
|
inconsistent.map((r) => ({ id: r.id, name: r.name, fillType: r.fill?.type })))
|
||||||
|
swalFire({ text: '面に屋根材パターンが描画されていますが、屋根材データが保存されていません。\n屋根材を再設定してから保存してください。', icon: 'warning' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 저장 전 선택되어 있는 object 제거
|
// 저장 전 선택되어 있는 object 제거
|
||||||
const setupSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
const setupSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user