create-hest-app 0.1.1 → 0.1.3
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/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/base_scalar/package.json +1 -1
- package/templates/base_scalar/src/index.ts +2 -3
- package/templates/cqrs_scalar/package.json +1 -1
- package/templates/cqrs_scalar/src/index.ts +2 -2
- package/templates/cqrs/src/test-error-scenarios.ts +0 -54
- package/templates/cqrs_scalar/src/test-error-scenarios.ts +0 -54
package/dist/index.js
CHANGED
@@ -113,7 +113,7 @@ ${Y.style.help(`(${D.instructions?.navigation??"Use arrow keys"})`)}`;let M=P8({
|
|
113
113
|
${Y.style.description(I.description)}`:"";return[[U,A,O].filter(Boolean).join(" "),`${P??M}${R}${$1}`]});var pF=e(_0(),1);var dE=e(M4(),1);var Ut={icon:{cursor:ED.pointer},style:{disabled:(D)=>pF.default.dim(`- ${D}`),description:(D)=>pF.default.cyan(D)},helpMode:"auto",indexMode:"hidden"};function y4(D){return!D1.isSeparator(D)&&!D.disabled}function Lt(D){return D.map(($)=>{if(D1.isSeparator($))return $;if(typeof $==="string")return{value:$,name:$,short:$,disabled:!1};let Z=$.name??String($.value),F={value:$.value,name:Z,short:$.short??Z,disabled:$.disabled??!1};if($.description)F.description=$.description;return F})}var w3=R1((D,$)=>{let{loop:Z=!0,pageSize:F=7}=D,Y=AD(!0),J=N1(Ut,D.theme),[X,Q]=h("idle"),q=M1({status:X,theme:J}),G=AD(),H=FD(()=>Lt(D.choices),[D.choices]),K=FD(()=>{let P=H.findIndex(y4),O=H.findLastIndex(y4);if(P===-1)throw new z0("[select prompt] No selectable choices. All choices are disabled.");return{first:P,last:O}},[H]),B=FD(()=>{if(!("default"in D))return-1;return H.findIndex((P)=>y4(P)&&P.value===D.default)},[D.default,H]),[z,U]=h(B===-1?K.first:B),L=H[z];T1((P,O)=>{if(clearTimeout(G.current),C1(P))Q("done"),$(L.value);else if(f0(P)||B4(P)){if(O.clearLine(0),Z||f0(P)&&z!==K.first||B4(P)&&z!==K.last){let $1=f0(P)?-1:1,T=z;do T=(T+$1+H.length)%H.length;while(!y4(H[T]));U(T)}}else if(Y3(P)&&!Number.isNaN(Number(O.line))){let $1=Number(O.line)-1,T=-1,C=H.findIndex((a)=>{if(D1.isSeparator(a))return!1;return T++,T===$1}),f=H[C];if(f!=null&&y4(f))U(C);G.current=setTimeout(()=>{O.clearLine(0)},700)}else if(V4(P))O.clearLine(0);else{let $1=O.line.toLowerCase(),T=H.findIndex((C)=>{if(D1.isSeparator(C)||!y4(C))return!1;return C.name.toLowerCase().startsWith($1)});if(T!==-1)U(T);G.current=setTimeout(()=>{O.clearLine(0)},700)}}),WD(()=>()=>{clearTimeout(G.current)},[]);let N=J.style.message(D.message,X),E="",I="";if(J.helpMode==="always"||J.helpMode==="auto"&&Y.current)if(Y.current=!1,H.length>F)I=`
|
114
114
|
${J.style.help(`(${D.instructions?.pager??"Use arrow keys to reveal more choices"})`)}`;else E=J.style.help(`(${D.instructions?.navigation??"Use arrow keys"})`);let A=0,R=P8({items:H,active:z,renderItem({item:P,isActive:O,index:$1}){if(D1.isSeparator(P))return A++,` ${P.separator}`;let T=J.indexMode==="number"?`${$1+1-A}. `:"";if(P.disabled){let a=typeof P.disabled==="string"?P.disabled:"(disabled)";return J.style.disabled(`${T}${P.name} ${a}`)}let C=O?J.style.highlight:(a)=>a,f=O?J.icon.cursor:" ";return C(`${f} ${T}${P.name}`)},pageSize:F,loop:Z});if(X==="done")return`${q} ${N} ${J.style.answer(L.short)}`;let M=L.description?`
|
115
115
|
${J.style.description(L.description)}`:"";return`${[q,N,E].filter(Boolean).join(" ")}
|
116
|
-
${R}${I}${M}${dE.default.cursorHide}`});var V1=e(pw(),1),qJ=e(aw(),1),tw=e(bZ(),1);import dY1 from"node:readline";var sw=e(M4(),1),ow={set:(D,$="",Z)=>{let F=D;$.split(".").forEach((Y,J,X)=>{if(Y==="__proto__"||Y==="constructor")return;if(J===X.length-1)F[Y]=Z;else if(!(Y in F)||typeof F[Y]!=="object")F[Y]={};F=F[Y]})},get:(D,$="",Z)=>{let F=(J)=>String.prototype.split.call($,J).filter(Boolean).reduce((X,Q)=>X==null?X:X[Q],D),Y=F(/[,[\]]+?/)||F(/[,.[\]]+?/);return Y===void 0||Y===D?Z:Y}};async function QJ(D,$,Z){let F=D[$];if(typeof F==="function")return qJ.default(F)(Z);return F}class rw extends Error{name="TTYError";isTtyError=!0}function pY1(D){D.skipTTYChecks=D.skipTTYChecks===void 0?!0:D.skipTTYChecks;let $=D.input||process.stdin;if(!D.skipTTYChecks&&!$.isTTY)throw new rw("Prompts can not be meaningfully rendered in non-TTY environments");let Z=new tw.default;return Z.pipe(D.output||process.stdout),{terminal:!0,...D,input:$,output:Z}}function cY1(D){return Array.isArray(D)}function nY1(D){return Object.values(D).every(($)=>typeof $==="object"&&!Array.isArray($)&&$!=null)}function iY1(D){return Boolean(D.prototype&&"run"in D.prototype&&typeof D.prototype.run==="function")}class f9{prompts;answers={};process=V1.EMPTY;abortController=new AbortController;opt;constructor(D,$={}){this.opt=$,this.prompts=D}async run(D,$){this.abortController=new AbortController,this.answers=typeof $==="object"?{...$}:{};let Z;if(cY1(D))Z=V1.from(D);else if(V1.isObservable(D))Z=D;else if(nY1(D))Z=V1.from(Object.entries(D).map(([F,Y])=>{return Object.assign({},Y,{name:F})}));else Z=V1.from([D]);return this.process=Z.pipe(V1.concatMap((F)=>V1.of(F).pipe(V1.concatMap((Y)=>V1.from(this.shouldRun(Y).then((J)=>{if(J)return Y;return})).pipe(V1.filter((J)=>J!=null))),V1.concatMap((Y)=>V1.defer(()=>V1.from(this.fetchAnswer(Y))))))),V1.lastValueFrom(this.process.pipe(V1.reduce((F,Y)=>{return ow.set(F,Y.name,Y.answer),F},this.answers))).then(()=>this.answers).finally(()=>this.close())}prepareQuestion=async(D)=>{let[$,Z,F]=await Promise.all([QJ(D,"message",this.answers),QJ(D,"default",this.answers),QJ(D,"choices",this.answers)]),Y;if(Array.isArray(F))Y=F.map((J)=>{let X=typeof J!=="object"||J==null?{name:J,value:J}:{...J,value:"value"in J?J.value:("name"in J)?J.name:void 0};if("value"in X&&Array.isArray(Z))return{checked:Z.includes(X.value),...X};return X});return Object.assign({},D,{message:$,default:Z,choices:Y,type:D.type in this.prompts?D.type:"input"})};fetchAnswer=async(D)=>{let $=await this.prepareQuestion(D),Z=this.prompts[$.type];if(Z==null)throw new Error(`Prompt for type ${$.type} not found`);let F,Y=iY1(Z)?(G,H)=>new Promise((K,B)=>{let{signal:z}=H;if(z.aborted){B(new U4({cause:z.reason}));return}let U=dY1.createInterface(pY1(H)),L=()=>{this.close(),process.kill(process.pid,"SIGINT"),console.log("")},N=()=>{process.removeListener("exit",L),U.removeListener("SIGINT",L),U.setPrompt(""),U.output.unmute(),U.output.write(sw.default.cursorShow),U.output.end(),U.close()};process.on("exit",L),U.on("SIGINT",L);let E=new Z(G,U,this.answers),I=()=>{N(),F?.()},A=()=>{B(new U4({cause:z.reason})),I()};z.addEventListener("abort",A),F=()=>{z.removeEventListener("abort",A),F=void 0},E.run().then(K,B).finally(I)}):Z,J,{signal:X}=this.opt;if(X?.aborted)this.abortController.abort(X.reason);else if(X){let G=()=>this.abortController.abort(X.reason);X.addEventListener("abort",G),J=()=>{X.removeEventListener("abort",G)}}let{filter:Q=(G)=>G}=$,{signal:q}=this.abortController;return Y($,{...this.opt,signal:q}).then((G)=>({name:$.name,answer:Q(G,this.answers)})).finally(()=>{F?.(),J?.()})};close=()=>{this.abortController.abort()};shouldRun=async(D)=>{if(D.askAnswered!==!0&&ow.get(this.answers,D.name)!==void 0)return!1;let{when:$}=D;if(typeof $==="function"){let Z=await qJ.default($)(this.answers);return Boolean(Z)}return $!==!1}}var ew={input:_F,select:w3,list:w3,number:hF,confirm:fF,rawlist:uF,expand:bF,checkbox:aZ,password:mF,editor:vF,search:dF};function Dk(D){function $(Z,F){let Y=new f9($.prompts,D),J=Y.run(Z,F);return Object.assign(J,{ui:Y})}return $.prompts={...ew},$.registerPrompt=function(Z,F){return $.prompts[Z]=F,this},$.restoreDefaultPrompts=function(){$.prompts={...ew}},$}var GJ=Dk();function aY1(D,$){GJ.registerPrompt(D,$)}function oY1(){GJ.restoreDefaultPrompts()}var tY1={prompt:GJ,ui:{Prompt:f9},createPromptModule:Dk,registerPrompt:aY1,restoreDefaultPrompts:oY1,Separator:D1},I0=tY1;var sY1=[{name:"Base - A simple HestJS application with basic features",value:"base"},{name:"CQRS - Complete application with CQRS pattern implementation",value:"cqrs"}],rY1=[{name:"npm",value:"npm"},{name:"yarn",value:"yarn"},{name:"pnpm",value:"pnpm"},{name:"bun",value:"bun"}];async function $k(){let{projectPath:D}=await I0.prompt({type:"input",name:"projectPath",message:"What is your project named?",default:"my-hest-app"});return D}async function Zk(D){let $={},{eslint:Z}=await I0.prompt({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",default:D.eslint});$.eslint=Z;let{template:F}=await I0.prompt({type:"list",name:"template",message:"Which template would you like to use?",choices:sY1,default:D.template});$.template=F;let{useSwagger:Y}=await I0.prompt({type:"confirm",name:"useSwagger",message:"Would you like to include Swagger/Scalar API documentation? (adds ~12MB to build size)",default:D.useSwagger});$.useSwagger=Y;let{packageManager:J}=await I0.prompt({type:"list",name:"packageManager",message:"Which package manager would you like to use?",choices:rY1,default:D.packageManager});$.packageManager=J;let{
|
116
|
+
${R}${I}${M}${dE.default.cursorHide}`});var V1=e(pw(),1),qJ=e(aw(),1),tw=e(bZ(),1);import dY1 from"node:readline";var sw=e(M4(),1),ow={set:(D,$="",Z)=>{let F=D;$.split(".").forEach((Y,J,X)=>{if(Y==="__proto__"||Y==="constructor")return;if(J===X.length-1)F[Y]=Z;else if(!(Y in F)||typeof F[Y]!=="object")F[Y]={};F=F[Y]})},get:(D,$="",Z)=>{let F=(J)=>String.prototype.split.call($,J).filter(Boolean).reduce((X,Q)=>X==null?X:X[Q],D),Y=F(/[,[\]]+?/)||F(/[,.[\]]+?/);return Y===void 0||Y===D?Z:Y}};async function QJ(D,$,Z){let F=D[$];if(typeof F==="function")return qJ.default(F)(Z);return F}class rw extends Error{name="TTYError";isTtyError=!0}function pY1(D){D.skipTTYChecks=D.skipTTYChecks===void 0?!0:D.skipTTYChecks;let $=D.input||process.stdin;if(!D.skipTTYChecks&&!$.isTTY)throw new rw("Prompts can not be meaningfully rendered in non-TTY environments");let Z=new tw.default;return Z.pipe(D.output||process.stdout),{terminal:!0,...D,input:$,output:Z}}function cY1(D){return Array.isArray(D)}function nY1(D){return Object.values(D).every(($)=>typeof $==="object"&&!Array.isArray($)&&$!=null)}function iY1(D){return Boolean(D.prototype&&"run"in D.prototype&&typeof D.prototype.run==="function")}class f9{prompts;answers={};process=V1.EMPTY;abortController=new AbortController;opt;constructor(D,$={}){this.opt=$,this.prompts=D}async run(D,$){this.abortController=new AbortController,this.answers=typeof $==="object"?{...$}:{};let Z;if(cY1(D))Z=V1.from(D);else if(V1.isObservable(D))Z=D;else if(nY1(D))Z=V1.from(Object.entries(D).map(([F,Y])=>{return Object.assign({},Y,{name:F})}));else Z=V1.from([D]);return this.process=Z.pipe(V1.concatMap((F)=>V1.of(F).pipe(V1.concatMap((Y)=>V1.from(this.shouldRun(Y).then((J)=>{if(J)return Y;return})).pipe(V1.filter((J)=>J!=null))),V1.concatMap((Y)=>V1.defer(()=>V1.from(this.fetchAnswer(Y))))))),V1.lastValueFrom(this.process.pipe(V1.reduce((F,Y)=>{return ow.set(F,Y.name,Y.answer),F},this.answers))).then(()=>this.answers).finally(()=>this.close())}prepareQuestion=async(D)=>{let[$,Z,F]=await Promise.all([QJ(D,"message",this.answers),QJ(D,"default",this.answers),QJ(D,"choices",this.answers)]),Y;if(Array.isArray(F))Y=F.map((J)=>{let X=typeof J!=="object"||J==null?{name:J,value:J}:{...J,value:"value"in J?J.value:("name"in J)?J.name:void 0};if("value"in X&&Array.isArray(Z))return{checked:Z.includes(X.value),...X};return X});return Object.assign({},D,{message:$,default:Z,choices:Y,type:D.type in this.prompts?D.type:"input"})};fetchAnswer=async(D)=>{let $=await this.prepareQuestion(D),Z=this.prompts[$.type];if(Z==null)throw new Error(`Prompt for type ${$.type} not found`);let F,Y=iY1(Z)?(G,H)=>new Promise((K,B)=>{let{signal:z}=H;if(z.aborted){B(new U4({cause:z.reason}));return}let U=dY1.createInterface(pY1(H)),L=()=>{this.close(),process.kill(process.pid,"SIGINT"),console.log("")},N=()=>{process.removeListener("exit",L),U.removeListener("SIGINT",L),U.setPrompt(""),U.output.unmute(),U.output.write(sw.default.cursorShow),U.output.end(),U.close()};process.on("exit",L),U.on("SIGINT",L);let E=new Z(G,U,this.answers),I=()=>{N(),F?.()},A=()=>{B(new U4({cause:z.reason})),I()};z.addEventListener("abort",A),F=()=>{z.removeEventListener("abort",A),F=void 0},E.run().then(K,B).finally(I)}):Z,J,{signal:X}=this.opt;if(X?.aborted)this.abortController.abort(X.reason);else if(X){let G=()=>this.abortController.abort(X.reason);X.addEventListener("abort",G),J=()=>{X.removeEventListener("abort",G)}}let{filter:Q=(G)=>G}=$,{signal:q}=this.abortController;return Y($,{...this.opt,signal:q}).then((G)=>({name:$.name,answer:Q(G,this.answers)})).finally(()=>{F?.(),J?.()})};close=()=>{this.abortController.abort()};shouldRun=async(D)=>{if(D.askAnswered!==!0&&ow.get(this.answers,D.name)!==void 0)return!1;let{when:$}=D;if(typeof $==="function"){let Z=await qJ.default($)(this.answers);return Boolean(Z)}return $!==!1}}var ew={input:_F,select:w3,list:w3,number:hF,confirm:fF,rawlist:uF,expand:bF,checkbox:aZ,password:mF,editor:vF,search:dF};function Dk(D){function $(Z,F){let Y=new f9($.prompts,D),J=Y.run(Z,F);return Object.assign(J,{ui:Y})}return $.prompts={...ew},$.registerPrompt=function(Z,F){return $.prompts[Z]=F,this},$.restoreDefaultPrompts=function(){$.prompts={...ew}},$}var GJ=Dk();function aY1(D,$){GJ.registerPrompt(D,$)}function oY1(){GJ.restoreDefaultPrompts()}var tY1={prompt:GJ,ui:{Prompt:f9},createPromptModule:Dk,registerPrompt:aY1,restoreDefaultPrompts:oY1,Separator:D1},I0=tY1;var sY1=[{name:"Base - A simple HestJS application with basic features",value:"base"},{name:"CQRS - Complete application with CQRS pattern implementation",value:"cqrs"}],rY1=[{name:"npm",value:"npm"},{name:"yarn",value:"yarn"},{name:"pnpm",value:"pnpm"},{name:"bun",value:"bun"}];async function $k(){let{projectPath:D}=await I0.prompt({type:"input",name:"projectPath",message:"What is your project named?",default:"my-hest-app"});return D}async function Zk(D){let $={},{eslint:Z}=await I0.prompt({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",default:D.eslint});$.eslint=Z;let{template:F}=await I0.prompt({type:"list",name:"template",message:"Which template would you like to use?",choices:sY1,default:D.template});$.template=F;let{useSwagger:Y}=await I0.prompt({type:"confirm",name:"useSwagger",message:"Would you like to include Swagger/Scalar API documentation? (adds ~12MB to build size)",default:D.useSwagger});$.useSwagger=Y;let{packageManager:J}=await I0.prompt({type:"list",name:"packageManager",message:"Which package manager would you like to use?",choices:rY1,default:D.packageManager});$.packageManager=J;let{installDependencies:X}=await I0.prompt({type:"confirm",name:"installDependencies",message:"Would you like to install dependencies?",default:!0});return $.skipInstall=!X,$}async function Fk(D){let{retry:$}=await I0.prompt({type:"confirm",name:"retry",message:`Could not download "${D}" because of a connectivity issue.
|
117
117
|
Do you want to try a different template?`,default:!0});return $}async function Yk(){let{alternativeExample:D}=await I0.prompt({type:"input",name:"alternativeExample",message:"Please specify an alternative template:"});return D}var HJ={name:"create-hest-app",version:"0.1.0"},Gk=()=>process.exit(0);process.on("SIGINT",Gk);process.on("SIGTERM",Gk);var o1=new wJ(HJ.name).version(HJ.version,"-v, --version","Output the current version of create-hest-app.").argument("[project-directory]").usage("[project-directory] [options]").helpOption("-h, --help","Display this help message.").option("--eslint","Initialize with ESLint config.").option("--no-eslint","Skip ESLint configuration.").option("--use-npm","Explicitly tell the CLI to bootstrap the application using npm.").option("--use-pnpm","Explicitly tell the CLI to bootstrap the application using pnpm.").option("--use-yarn","Explicitly tell the CLI to bootstrap the application using Yarn.").option("--use-bun","Explicitly tell the CLI to bootstrap the application using Bun.").option("--skip-install","Explicitly tell the CLI to skip installing packages.").option("--template <template-name>","Specify the template to use (base, cqrs).").allowUnknownOption().parse(process.argv),DJ1=async()=>{let D=new b5({projectName:"create-hest-app"});if(o1.opts().resetPreferences){D.clear(),console.log(`${GD.green("✓")} Preferences reset successfully`);return}let $=o1.args[0];if(!$)$=await $k();if(typeof $==="string")$=$.trim();let Z=Jk(Xk($)),F=oU(Z);if(!F.valid)console.error(`Could not create a project called ${GD.red(`"${Z}"`)} because of npm naming restrictions:`),F.problems.forEach((z)=>console.error(` ${GD.red(GD.bold("*"))} ${z}`)),process.exit(1);let Y=Xk($),J=Jk(Y);if(eY1(Y)&&!c5(Y,J))process.exit(1);let Q=D.get("preferences")||{},q={eslint:!0,skipInstall:!1,template:"base",useSwagger:!1,packageManager:CZ()},G=(z)=>Q[z]??q[z],H={};if(!(o1.opts().eslint!==void 0||o1.opts().template||o1.opts().useNpm||o1.opts().usePnpm||o1.opts().useYarn||o1.opts().useBun))H=await Zk({...q,eslint:G("eslint"),template:G("template"),useSwagger:G("useSwagger"),packageManager:G("packageManager")});let B={eslint:o1.opts().eslint??H.eslint??q.eslint,skipInstall:o1.opts().skipInstall??H.skipInstall??q.skipInstall,template:o1.opts().template??H.template??q.template,useSwagger:H.useSwagger??q.useSwagger,packageManager:(()=>{if(o1.opts().useNpm)return"npm";if(o1.opts().usePnpm)return"pnpm";if(o1.opts().useYarn)return"yarn";if(o1.opts().useBun)return"bun";return H.packageManager??q.packageManager})()};Object.assign(Q,H),D.set("preferences",Q);try{await PZ({appPath:$,packageManager:B.packageManager,eslint:B.eslint,skipInstall:B.skipInstall,template:B.template,useSwagger:B.useSwagger})}catch(z){if(!(z instanceof F3))throw z;if(!await Fk(B.template))process.exit(0);let L=await Yk();await PZ({appPath:$,packageManager:B.packageManager,eslint:B.eslint,skipInstall:B.skipInstall,template:L,useSwagger:B.useSwagger})}},$J1=qk.default({pkg:HJ,updateCheckUrl:"https://registry.npmjs.org/create-hest-app/latest"}).catch(()=>null);async function Qk(){try{if((await $J1)?.latest){let $=CZ(),Z=$==="yarn"?"yarn global add create-hest-app":$==="pnpm"?"pnpm add -g create-hest-app":$==="bun"?"bun add -g create-hest-app":"npm i -g create-hest-app";console.log(GD.yellow(GD.bold("A new version of `create-hest-app` is available!"))+`
|
118
118
|
You can update by running: `+GD.cyan(Z)+`
|
119
119
|
`)}process.exit()}catch{}}DJ1().then(Qk).catch(async(D)=>{if(console.log(),console.log("Aborting installation."),D.command)console.log(` ${GD.cyan(D.command)} has failed.`);else console.log(GD.red("Unexpected error. Please report it as a bug:")+`
|
package/package.json
CHANGED
@@ -23,9 +23,8 @@ async function bootstrap() {
|
|
23
23
|
// 全局异常过滤器
|
24
24
|
app.useGlobalFilters(new HttpExceptionFilter());
|
25
25
|
|
26
|
-
// 设置OpenAPI规范端点
|
27
|
-
app.
|
28
|
-
[AppController], // 传入需要生成文档的控制器
|
26
|
+
// 设置OpenAPI规范端点
|
27
|
+
app.useSwagger(
|
29
28
|
{
|
30
29
|
info: {
|
31
30
|
title: 'HestJS Demo API',
|
@@ -1,54 +0,0 @@
|
|
1
|
-
import { logger } from '@hestjs/logger';
|
2
|
-
|
3
|
-
// 模拟应用启动时的错误处理
|
4
|
-
async function testErrorScenarios() {
|
5
|
-
console.log('=== Testing Real-world Error Scenarios ===\n');
|
6
|
-
|
7
|
-
// 场景 1: 数据库连接错误
|
8
|
-
try {
|
9
|
-
throw new Error('Database connection failed');
|
10
|
-
} catch (error) {
|
11
|
-
logger.error(
|
12
|
-
'❌ Failed to connect to database:',
|
13
|
-
error instanceof Error ? error : new Error(String(error)),
|
14
|
-
);
|
15
|
-
}
|
16
|
-
|
17
|
-
// 场景 2: API 调用失败
|
18
|
-
try {
|
19
|
-
const apiError = new Error('API request timeout');
|
20
|
-
(apiError as any).status = 504;
|
21
|
-
(apiError as any).endpoint = '/api/users';
|
22
|
-
throw apiError;
|
23
|
-
} catch (error) {
|
24
|
-
logger.error(
|
25
|
-
'❌ API call failed:',
|
26
|
-
error instanceof Error ? error : new Error(String(error)),
|
27
|
-
{
|
28
|
-
requestId: 'req-12345',
|
29
|
-
userId: 'user-67890',
|
30
|
-
},
|
31
|
-
);
|
32
|
-
}
|
33
|
-
|
34
|
-
// 场景 3: 验证错误
|
35
|
-
try {
|
36
|
-
const validationError = new Error('Validation failed');
|
37
|
-
(validationError as any).fields = ['email', 'password'];
|
38
|
-
(validationError as any).code = 'VALIDATION_ERROR';
|
39
|
-
throw validationError;
|
40
|
-
} catch (error) {
|
41
|
-
logger.error(
|
42
|
-
'❌ Validation failed:',
|
43
|
-
error instanceof Error ? error : new Error(String(error)),
|
44
|
-
);
|
45
|
-
}
|
46
|
-
|
47
|
-
// 场景 4: 使用简化的语法
|
48
|
-
const simpleError = new Error('Something went wrong');
|
49
|
-
logger.error('❌ Simple error logging:', simpleError);
|
50
|
-
|
51
|
-
console.log('\n=== Test Complete ===');
|
52
|
-
}
|
53
|
-
|
54
|
-
testErrorScenarios();
|
@@ -1,54 +0,0 @@
|
|
1
|
-
import { logger } from '@hestjs/logger';
|
2
|
-
|
3
|
-
// 模拟应用启动时的错误处理
|
4
|
-
async function testErrorScenarios() {
|
5
|
-
console.log('=== Testing Real-world Error Scenarios ===\n');
|
6
|
-
|
7
|
-
// 场景 1: 数据库连接错误
|
8
|
-
try {
|
9
|
-
throw new Error('Database connection failed');
|
10
|
-
} catch (error) {
|
11
|
-
logger.error(
|
12
|
-
'❌ Failed to connect to database:',
|
13
|
-
error instanceof Error ? error : new Error(String(error)),
|
14
|
-
);
|
15
|
-
}
|
16
|
-
|
17
|
-
// 场景 2: API 调用失败
|
18
|
-
try {
|
19
|
-
const apiError = new Error('API request timeout');
|
20
|
-
(apiError as any).status = 504;
|
21
|
-
(apiError as any).endpoint = '/api/users';
|
22
|
-
throw apiError;
|
23
|
-
} catch (error) {
|
24
|
-
logger.error(
|
25
|
-
'❌ API call failed:',
|
26
|
-
error instanceof Error ? error : new Error(String(error)),
|
27
|
-
{
|
28
|
-
requestId: 'req-12345',
|
29
|
-
userId: 'user-67890',
|
30
|
-
},
|
31
|
-
);
|
32
|
-
}
|
33
|
-
|
34
|
-
// 场景 3: 验证错误
|
35
|
-
try {
|
36
|
-
const validationError = new Error('Validation failed');
|
37
|
-
(validationError as any).fields = ['email', 'password'];
|
38
|
-
(validationError as any).code = 'VALIDATION_ERROR';
|
39
|
-
throw validationError;
|
40
|
-
} catch (error) {
|
41
|
-
logger.error(
|
42
|
-
'❌ Validation failed:',
|
43
|
-
error instanceof Error ? error : new Error(String(error)),
|
44
|
-
);
|
45
|
-
}
|
46
|
-
|
47
|
-
// 场景 4: 使用简化的语法
|
48
|
-
const simpleError = new Error('Something went wrong');
|
49
|
-
logger.error('❌ Simple error logging:', simpleError);
|
50
|
-
|
51
|
-
console.log('\n=== Test Complete ===');
|
52
|
-
}
|
53
|
-
|
54
|
-
testErrorScenarios();
|