@mandujs/core 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +200 -200
- package/README.md +200 -200
- package/package.json +4 -2
- package/src/change/history.ts +145 -0
- package/src/change/index.ts +40 -0
- package/src/change/integrity.ts +81 -0
- package/src/change/snapshot.ts +233 -0
- package/src/change/transaction.ts +293 -0
- package/src/change/types.ts +102 -0
- package/src/error/classifier.ts +314 -0
- package/src/error/formatter.ts +237 -0
- package/src/error/index.ts +25 -0
- package/src/error/stack-analyzer.ts +295 -0
- package/src/error/types.ts +140 -0
- package/src/filling/context.ts +228 -219
- package/src/filling/filling.ts +256 -234
- package/src/filling/index.ts +7 -7
- package/src/generator/generate.ts +85 -3
- package/src/generator/index.ts +2 -2
- package/src/guard/auto-correct.ts +257 -203
- package/src/index.ts +3 -0
- package/src/report/index.ts +1 -1
- package/src/runtime/index.ts +3 -3
- package/src/runtime/router.ts +65 -65
- package/src/runtime/server.ts +189 -139
- package/src/runtime/ssr.ts +38 -38
- package/src/slot/corrector.ts +282 -0
- package/src/slot/index.ts +18 -0
- package/src/slot/validator.ts +241 -0
- package/src/spec/index.ts +3 -3
- package/src/spec/load.ts +76 -76
- package/src/spec/lock.ts +56 -56
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import type { GeneratedMap } from "../generator/generate";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 스택 프레임 정보
|
|
5
|
+
*/
|
|
6
|
+
export interface StackFrame {
|
|
7
|
+
/** 파일 경로 */
|
|
8
|
+
file: string;
|
|
9
|
+
/** 라인 번호 */
|
|
10
|
+
line: number;
|
|
11
|
+
/** 컬럼 번호 (선택) */
|
|
12
|
+
column?: number;
|
|
13
|
+
/** 함수 이름 (선택) */
|
|
14
|
+
functionName?: string;
|
|
15
|
+
/** 네이티브 코드 여부 */
|
|
16
|
+
isNative: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 스택 트레이스 분석기
|
|
21
|
+
*/
|
|
22
|
+
export class StackTraceAnalyzer {
|
|
23
|
+
/** Generated 파일 매핑 */
|
|
24
|
+
private generatedMap: GeneratedMap | null;
|
|
25
|
+
/** 프로젝트 루트 디렉토리 */
|
|
26
|
+
private rootDir: string;
|
|
27
|
+
|
|
28
|
+
constructor(generatedMap: GeneratedMap | null = null, rootDir: string = process.cwd()) {
|
|
29
|
+
this.generatedMap = generatedMap;
|
|
30
|
+
this.rootDir = rootDir;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Error.stack 문자열을 구조화된 프레임으로 파싱
|
|
35
|
+
*/
|
|
36
|
+
parseStack(stack: string | undefined): StackFrame[] {
|
|
37
|
+
if (!stack) return [];
|
|
38
|
+
|
|
39
|
+
const frames: StackFrame[] = [];
|
|
40
|
+
const lines = stack.split("\n");
|
|
41
|
+
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
const frame = this.parseStackLine(line);
|
|
44
|
+
if (frame) {
|
|
45
|
+
frames.push(frame);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return frames;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 단일 스택 라인 파싱
|
|
54
|
+
* V8/Bun 형식: " at functionName (file:line:column)"
|
|
55
|
+
* 또는 " at file:line:column"
|
|
56
|
+
*/
|
|
57
|
+
private parseStackLine(line: string): StackFrame | null {
|
|
58
|
+
const trimmed = line.trim();
|
|
59
|
+
|
|
60
|
+
// "at " 로 시작하지 않으면 스킵
|
|
61
|
+
if (!trimmed.startsWith("at ")) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const content = trimmed.slice(3); // "at " 제거
|
|
66
|
+
|
|
67
|
+
// 네이티브 코드 체크
|
|
68
|
+
if (content.includes("[native code]") || content.startsWith("native")) {
|
|
69
|
+
return {
|
|
70
|
+
file: "native",
|
|
71
|
+
line: 0,
|
|
72
|
+
isNative: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 패턴 1: "functionName (file:line:column)"
|
|
77
|
+
const withFnMatch = content.match(/^(.+?)\s+\((.+?):(\d+):(\d+)\)$/);
|
|
78
|
+
if (withFnMatch) {
|
|
79
|
+
return {
|
|
80
|
+
functionName: withFnMatch[1],
|
|
81
|
+
file: this.normalizePath(withFnMatch[2]),
|
|
82
|
+
line: parseInt(withFnMatch[3], 10),
|
|
83
|
+
column: parseInt(withFnMatch[4], 10),
|
|
84
|
+
isNative: false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 패턴 2: "functionName (file:line)"
|
|
89
|
+
const withFnNoColMatch = content.match(/^(.+?)\s+\((.+?):(\d+)\)$/);
|
|
90
|
+
if (withFnNoColMatch) {
|
|
91
|
+
return {
|
|
92
|
+
functionName: withFnNoColMatch[1],
|
|
93
|
+
file: this.normalizePath(withFnNoColMatch[2]),
|
|
94
|
+
line: parseInt(withFnNoColMatch[3], 10),
|
|
95
|
+
isNative: false,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 패턴 3: "file:line:column"
|
|
100
|
+
const noFnMatch = content.match(/^(.+?):(\d+):(\d+)$/);
|
|
101
|
+
if (noFnMatch) {
|
|
102
|
+
return {
|
|
103
|
+
file: this.normalizePath(noFnMatch[1]),
|
|
104
|
+
line: parseInt(noFnMatch[2], 10),
|
|
105
|
+
column: parseInt(noFnMatch[3], 10),
|
|
106
|
+
isNative: false,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 패턴 4: "file:line"
|
|
111
|
+
const noFnNoColMatch = content.match(/^(.+?):(\d+)$/);
|
|
112
|
+
if (noFnNoColMatch) {
|
|
113
|
+
return {
|
|
114
|
+
file: this.normalizePath(noFnNoColMatch[1]),
|
|
115
|
+
line: parseInt(noFnNoColMatch[2], 10),
|
|
116
|
+
isNative: false,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 파일 경로 정규화 (상대 경로로 변환)
|
|
125
|
+
*/
|
|
126
|
+
private normalizePath(filePath: string): string {
|
|
127
|
+
// Windows 경로 정규화
|
|
128
|
+
let normalized = filePath.replace(/\\/g, "/");
|
|
129
|
+
|
|
130
|
+
// 프로젝트 루트 제거
|
|
131
|
+
const rootNormalized = this.rootDir.replace(/\\/g, "/");
|
|
132
|
+
if (normalized.startsWith(rootNormalized)) {
|
|
133
|
+
normalized = normalized.slice(rootNormalized.length);
|
|
134
|
+
if (normalized.startsWith("/")) {
|
|
135
|
+
normalized = normalized.slice(1);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return normalized;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Generated 파일인지 확인
|
|
144
|
+
*/
|
|
145
|
+
isGeneratedFile(file: string): boolean {
|
|
146
|
+
if (!this.generatedMap) return false;
|
|
147
|
+
|
|
148
|
+
const normalized = this.normalizePath(file);
|
|
149
|
+
return normalized in this.generatedMap.files;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Slot 파일인지 확인
|
|
154
|
+
*/
|
|
155
|
+
isSlotFile(file: string): boolean {
|
|
156
|
+
const normalized = this.normalizePath(file);
|
|
157
|
+
|
|
158
|
+
// slots 디렉토리 내 파일
|
|
159
|
+
if (normalized.includes("/slots/") || normalized.includes("\\slots\\")) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// spec/slots 패턴
|
|
164
|
+
if (normalized.startsWith("spec/slots/")) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// GeneratedMap의 slotMapping 확인
|
|
169
|
+
if (this.generatedMap) {
|
|
170
|
+
for (const entry of Object.values(this.generatedMap.files)) {
|
|
171
|
+
if (entry.slotMapping?.slotPath === normalized) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Spec 파일인지 확인
|
|
182
|
+
*/
|
|
183
|
+
isSpecFile(file: string): boolean {
|
|
184
|
+
const normalized = this.normalizePath(file);
|
|
185
|
+
|
|
186
|
+
// spec/ 디렉토리 내 JSON 파일
|
|
187
|
+
if (normalized.startsWith("spec/") && normalized.endsWith(".json")) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// spec 로더/스키마 파일
|
|
192
|
+
if (normalized.includes("spec/load") || normalized.includes("spec/schema")) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 프레임워크 내부 파일인지 확인
|
|
201
|
+
*/
|
|
202
|
+
isFrameworkFile(file: string): boolean {
|
|
203
|
+
const normalized = this.normalizePath(file);
|
|
204
|
+
|
|
205
|
+
// @mandujs/core 패키지
|
|
206
|
+
if (normalized.includes("@mandujs/core")) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// packages/core/src 내부
|
|
211
|
+
if (normalized.includes("packages/core/src")) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// node_modules 내부 (프레임워크 제외한 외부 라이브러리)
|
|
216
|
+
if (normalized.includes("node_modules") && !normalized.includes("@mandujs")) {
|
|
217
|
+
return false; // 외부 라이브러리는 프레임워크로 취급 안 함
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// GeneratedMap의 frameworkPaths 확인
|
|
221
|
+
if (this.generatedMap?.frameworkPaths) {
|
|
222
|
+
for (const pattern of this.generatedMap.frameworkPaths) {
|
|
223
|
+
if (normalized.includes(pattern)) {
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* 스택에서 "blame frame" 찾기 (첫 번째 사용자 관련 프레임)
|
|
234
|
+
*/
|
|
235
|
+
findBlameFrame(frames: StackFrame[]): StackFrame | null {
|
|
236
|
+
for (const frame of frames) {
|
|
237
|
+
if (frame.isNative) continue;
|
|
238
|
+
|
|
239
|
+
// Slot 파일 우선
|
|
240
|
+
if (this.isSlotFile(frame.file)) {
|
|
241
|
+
return frame;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Spec 파일
|
|
245
|
+
if (this.isSpecFile(frame.file)) {
|
|
246
|
+
return frame;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Slot/Spec이 없으면 첫 번째 non-native 프레임
|
|
251
|
+
for (const frame of frames) {
|
|
252
|
+
if (!frame.isNative && !this.isFrameworkFile(frame.file)) {
|
|
253
|
+
return frame;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Generated 파일 위치를 Slot 위치로 매핑
|
|
262
|
+
*/
|
|
263
|
+
mapToSlotLocation(generatedFile: string, _line: number): { file: string; line: number } | null {
|
|
264
|
+
if (!this.generatedMap) return null;
|
|
265
|
+
|
|
266
|
+
const normalized = this.normalizePath(generatedFile);
|
|
267
|
+
const entry = this.generatedMap.files[normalized];
|
|
268
|
+
|
|
269
|
+
if (!entry?.slotMapping) return null;
|
|
270
|
+
|
|
271
|
+
// Slot 파일의 시작 위치 반환 (정확한 라인 매핑은 향후 개선)
|
|
272
|
+
return {
|
|
273
|
+
file: entry.slotMapping.slotPath,
|
|
274
|
+
line: 1,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* 에러 출처 타입 결정
|
|
280
|
+
*/
|
|
281
|
+
determineErrorSource(
|
|
282
|
+
frames: StackFrame[]
|
|
283
|
+
): "slot" | "spec" | "generated" | "framework" | "unknown" {
|
|
284
|
+
for (const frame of frames) {
|
|
285
|
+
if (frame.isNative) continue;
|
|
286
|
+
|
|
287
|
+
if (this.isSlotFile(frame.file)) return "slot";
|
|
288
|
+
if (this.isSpecFile(frame.file)) return "spec";
|
|
289
|
+
if (this.isGeneratedFile(frame.file)) return "generated";
|
|
290
|
+
if (this.isFrameworkFile(frame.file)) return "framework";
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return "unknown";
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 에러 타입 분류
|
|
3
|
+
*/
|
|
4
|
+
export type ErrorType = "SPEC_ERROR" | "LOGIC_ERROR" | "FRAMEWORK_BUG";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 에러 코드 체계
|
|
8
|
+
* - SPEC_ERROR: E1xx
|
|
9
|
+
* - LOGIC_ERROR: E2xx
|
|
10
|
+
* - FRAMEWORK_BUG: Fxxx
|
|
11
|
+
*/
|
|
12
|
+
export enum ErrorCode {
|
|
13
|
+
// SPEC_ERROR (1xx)
|
|
14
|
+
SPEC_NOT_FOUND = "MANDU_E101",
|
|
15
|
+
SPEC_PARSE_ERROR = "MANDU_E102",
|
|
16
|
+
SPEC_VALIDATION_ERROR = "MANDU_E103",
|
|
17
|
+
SPEC_ROUTE_DUPLICATE = "MANDU_E104",
|
|
18
|
+
SPEC_ROUTE_NOT_FOUND = "MANDU_E105",
|
|
19
|
+
|
|
20
|
+
// LOGIC_ERROR (2xx)
|
|
21
|
+
SLOT_NOT_FOUND = "MANDU_E201",
|
|
22
|
+
SLOT_IMPORT_ERROR = "MANDU_E202",
|
|
23
|
+
SLOT_RUNTIME_ERROR = "MANDU_E203",
|
|
24
|
+
SLOT_VALIDATION_ERROR = "MANDU_E204",
|
|
25
|
+
SLOT_HANDLER_ERROR = "MANDU_E205",
|
|
26
|
+
|
|
27
|
+
// FRAMEWORK_BUG (Fxx)
|
|
28
|
+
FRAMEWORK_GENERATOR_ERROR = "MANDU_F001",
|
|
29
|
+
FRAMEWORK_SSR_ERROR = "MANDU_F002",
|
|
30
|
+
FRAMEWORK_ROUTER_ERROR = "MANDU_F003",
|
|
31
|
+
FRAMEWORK_INTERNAL = "MANDU_F999",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 수정 대상 정보
|
|
36
|
+
*/
|
|
37
|
+
export interface FixTarget {
|
|
38
|
+
/** 수정해야 할 파일 경로 */
|
|
39
|
+
file: string;
|
|
40
|
+
/** 수정 가이드 */
|
|
41
|
+
suggestion: string;
|
|
42
|
+
/** 라인 번호 (선택) */
|
|
43
|
+
line?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 라우트 컨텍스트
|
|
48
|
+
*/
|
|
49
|
+
export interface RouteContext {
|
|
50
|
+
/** 라우트 ID */
|
|
51
|
+
id: string;
|
|
52
|
+
/** URL 패턴 */
|
|
53
|
+
pattern: string;
|
|
54
|
+
/** 라우트 종류 */
|
|
55
|
+
kind?: "api" | "page";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 디버그 정보 (개발 모드에서만 포함)
|
|
60
|
+
*/
|
|
61
|
+
export interface DebugInfo {
|
|
62
|
+
/** 스택 트레이스 */
|
|
63
|
+
stack: string;
|
|
64
|
+
/** 원본 에러 메시지 */
|
|
65
|
+
originalError: string;
|
|
66
|
+
/** Generated 파일 경로 (있는 경우) */
|
|
67
|
+
generatedFile?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Mandu 에러 응답 구조
|
|
72
|
+
*/
|
|
73
|
+
export interface ManduError {
|
|
74
|
+
/** 에러 타입 */
|
|
75
|
+
errorType: ErrorType;
|
|
76
|
+
/** 에러 코드 */
|
|
77
|
+
code: ErrorCode | string;
|
|
78
|
+
/** 에러 메시지 */
|
|
79
|
+
message: string;
|
|
80
|
+
/** 한줄 요약 (에이전트용) */
|
|
81
|
+
summary: string;
|
|
82
|
+
/** 수정 대상 정보 */
|
|
83
|
+
fix: FixTarget;
|
|
84
|
+
/** 라우트 컨텍스트 (있는 경우) */
|
|
85
|
+
route?: RouteContext;
|
|
86
|
+
/** 디버그 정보 (개발 모드) */
|
|
87
|
+
debug?: DebugInfo;
|
|
88
|
+
/** 타임스탬프 */
|
|
89
|
+
timestamp: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 에러 코드 → 메시지 매핑
|
|
94
|
+
*/
|
|
95
|
+
export const ERROR_MESSAGES: Record<ErrorCode, string> = {
|
|
96
|
+
// SPEC_ERROR
|
|
97
|
+
[ErrorCode.SPEC_NOT_FOUND]: "Spec 파일을 찾을 수 없습니다",
|
|
98
|
+
[ErrorCode.SPEC_PARSE_ERROR]: "Spec 파일 파싱 오류",
|
|
99
|
+
[ErrorCode.SPEC_VALIDATION_ERROR]: "Spec 스키마 검증 실패",
|
|
100
|
+
[ErrorCode.SPEC_ROUTE_DUPLICATE]: "라우트 패턴 중복",
|
|
101
|
+
[ErrorCode.SPEC_ROUTE_NOT_FOUND]: "라우트를 찾을 수 없습니다",
|
|
102
|
+
|
|
103
|
+
// LOGIC_ERROR
|
|
104
|
+
[ErrorCode.SLOT_NOT_FOUND]: "Slot 파일을 찾을 수 없습니다",
|
|
105
|
+
[ErrorCode.SLOT_IMPORT_ERROR]: "Slot 파일 import 오류",
|
|
106
|
+
[ErrorCode.SLOT_RUNTIME_ERROR]: "Slot 런타임 오류",
|
|
107
|
+
[ErrorCode.SLOT_VALIDATION_ERROR]: "입력 검증 실패",
|
|
108
|
+
[ErrorCode.SLOT_HANDLER_ERROR]: "핸들러 실행 오류",
|
|
109
|
+
|
|
110
|
+
// FRAMEWORK_BUG
|
|
111
|
+
[ErrorCode.FRAMEWORK_GENERATOR_ERROR]: "Generator 내부 오류",
|
|
112
|
+
[ErrorCode.FRAMEWORK_SSR_ERROR]: "SSR 렌더링 오류",
|
|
113
|
+
[ErrorCode.FRAMEWORK_ROUTER_ERROR]: "Router 내부 오류",
|
|
114
|
+
[ErrorCode.FRAMEWORK_INTERNAL]: "알 수 없는 내부 오류",
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 에러 코드 → 요약 매핑
|
|
119
|
+
*/
|
|
120
|
+
export const ERROR_SUMMARIES: Record<ErrorCode, string> = {
|
|
121
|
+
// SPEC_ERROR
|
|
122
|
+
[ErrorCode.SPEC_NOT_FOUND]: "Spec 파일 없음 - spec 디렉토리 확인 필요",
|
|
123
|
+
[ErrorCode.SPEC_PARSE_ERROR]: "Spec 파싱 오류 - JSON 문법 확인 필요",
|
|
124
|
+
[ErrorCode.SPEC_VALIDATION_ERROR]: "Spec 검증 실패 - 스키마 확인 필요",
|
|
125
|
+
[ErrorCode.SPEC_ROUTE_DUPLICATE]: "라우트 중복 - spec 파일 수정 필요",
|
|
126
|
+
[ErrorCode.SPEC_ROUTE_NOT_FOUND]: "라우트 없음 - spec 파일에 추가 필요",
|
|
127
|
+
|
|
128
|
+
// LOGIC_ERROR
|
|
129
|
+
[ErrorCode.SLOT_NOT_FOUND]: "Slot 파일 없음 - generate 실행 필요",
|
|
130
|
+
[ErrorCode.SLOT_IMPORT_ERROR]: "Slot import 오류 - slot 파일 확인 필요",
|
|
131
|
+
[ErrorCode.SLOT_RUNTIME_ERROR]: "Slot 런타임 오류 - slot 파일 수정 필요",
|
|
132
|
+
[ErrorCode.SLOT_VALIDATION_ERROR]: "입력 검증 실패 - 요청 데이터 확인 필요",
|
|
133
|
+
[ErrorCode.SLOT_HANDLER_ERROR]: "핸들러 오류 - slot 파일 수정 필요",
|
|
134
|
+
|
|
135
|
+
// FRAMEWORK_BUG
|
|
136
|
+
[ErrorCode.FRAMEWORK_GENERATOR_ERROR]: "Generator 오류 - 버그 리포트 필요",
|
|
137
|
+
[ErrorCode.FRAMEWORK_SSR_ERROR]: "SSR 오류 - 버그 리포트 필요",
|
|
138
|
+
[ErrorCode.FRAMEWORK_ROUTER_ERROR]: "Router 오류 - 버그 리포트 필요",
|
|
139
|
+
[ErrorCode.FRAMEWORK_INTERNAL]: "내부 오류 - 버그 리포트 필요",
|
|
140
|
+
};
|