Fraser commited on
Commit
e6edab1
·
1 Parent(s): 1eac263

error handling

Browse files
src/lib/components/MonsterGenerator/MonsterGenerator.svelte CHANGED
@@ -83,12 +83,49 @@ Assistant:`;
83
  state.currentStep = 'complete';
84
  } catch (err) {
85
  console.error('Workflow error:', err);
86
- state.error = err instanceof Error ? err.message : 'An unknown error occurred';
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  } finally {
88
  state.isProcessing = false;
89
  }
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  async function captionImage() {
93
  state.currentStep = 'captioning';
94
 
@@ -96,18 +133,22 @@ Assistant:`;
96
  throw new Error('Caption service not available or no image provided');
97
  }
98
 
99
- const output = await joyCaptionClient.predict("/stream_chat", [
100
- state.userImage,
101
- "Descriptive" as CaptionType,
102
- "very long" as CaptionLength,
103
- [], // extra_options
104
- "", // name_input
105
- "" // custom_prompt
106
- ]);
107
-
108
- const [prompt, caption] = output.data;
109
- state.imageCaption = caption;
110
- console.log('Caption generated:', caption);
 
 
 
 
111
  }
112
 
113
  async function generateMonsterConcept() {
@@ -121,21 +162,25 @@ Assistant:`;
121
 
122
  console.log('Generating monster concept with prompt:', conceptPrompt);
123
 
124
- const output = await rwkvClient.predict(0, [
125
- conceptPrompt,
126
- 300, // maxTokens
127
- 0.7, // temperature
128
- 0.8, // topP
129
- 0.1, // presencePenalty
130
- 0.1 // countPenalty
131
- ]);
132
-
133
- console.log('RWKV output:', output);
134
- state.monsterConcept = output.data[0];
135
- console.log('Monster concept generated:', state.monsterConcept);
136
-
137
- if (!state.monsterConcept || state.monsterConcept.trim() === '') {
138
- throw new Error('Failed to generate monster concept - received empty response');
 
 
 
 
139
  }
140
  }
141
 
@@ -150,21 +195,25 @@ Assistant:`;
150
 
151
  console.log('Generating image prompt from concept');
152
 
153
- const output = await rwkvClient.predict(0, [
154
- promptGenerationPrompt,
155
- 300, // maxTokens
156
- 0.7, // temperature
157
- 0.8, // topP
158
- 0.1, // presencePenalty
159
- 0.1 // countPenalty
160
- ]);
161
-
162
- console.log('Image prompt output:', output);
163
- state.imagePrompt = output.data[0];
164
- console.log('Image prompt generated:', state.imagePrompt);
165
-
166
- if (!state.imagePrompt || state.imagePrompt.trim() === '') {
167
- throw new Error('Failed to generate image prompt - received empty response');
 
 
 
 
168
  }
169
  }
170
 
@@ -175,30 +224,34 @@ Assistant:`;
175
  throw new Error('Image generation service not available or no prompt');
176
  }
177
 
178
- const output = await fluxClient.predict("/infer", [
179
- `${state.imagePrompt}\nNow generate an Anime-style image of the monster in an idle pose. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
180
- 0, // seed
181
- true, // randomizeSeed
182
- 1024, // width
183
- 1024, // height
184
- 4 // steps
185
- ]);
186
-
187
- const [image, usedSeed] = output.data;
188
- let url: string | undefined;
189
-
190
- if (typeof image === "string") url = image;
191
- else if (image && image.url) url = image.url;
192
- else if (image && image.path) url = image.path;
193
-
194
- if (url) {
195
- state.monsterImage = {
196
- imageUrl: url,
197
- seed: usedSeed,
198
- prompt: state.imagePrompt
199
- };
200
- } else {
201
- throw new Error('Failed to generate monster image');
 
 
 
 
202
  }
203
  }
204
 
 
83
  state.currentStep = 'complete';
84
  } catch (err) {
85
  console.error('Workflow error:', err);
86
+
87
+ // Check for GPU quota error
88
+ if (err && typeof err === 'object' && 'message' in err) {
89
+ const errorMessage = String(err.message);
90
+ if (errorMessage.includes('exceeded your GPU quota') || errorMessage.includes('GPU quota')) {
91
+ state.error = 'GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.';
92
+ } else {
93
+ state.error = errorMessage;
94
+ }
95
+ } else if (err instanceof Error) {
96
+ state.error = err.message;
97
+ } else {
98
+ state.error = 'An unknown error occurred';
99
+ }
100
  } finally {
101
  state.isProcessing = false;
102
  }
103
  }
104
 
105
+ function handleAPIError(error: any): never {
106
+ console.error('API Error:', error);
107
+
108
+ // Check if it's a GPU quota error
109
+ if (error && typeof error === 'object' && 'message' in error) {
110
+ const errorMessage = String(error.message);
111
+ if (errorMessage.includes('exceeded your GPU quota') || errorMessage.includes('GPU quota')) {
112
+ throw new Error('GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.');
113
+ }
114
+ throw new Error(errorMessage);
115
+ }
116
+
117
+ // Check if error has a different structure (like the status object from the logs)
118
+ if (error && typeof error === 'object' && 'type' in error && error.type === 'status') {
119
+ const statusError = error as any;
120
+ if (statusError.message && statusError.message.includes('GPU quota')) {
121
+ throw new Error('GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.');
122
+ }
123
+ throw new Error(statusError.message || 'API request failed');
124
+ }
125
+
126
+ throw error;
127
+ }
128
+
129
  async function captionImage() {
130
  state.currentStep = 'captioning';
131
 
 
133
  throw new Error('Caption service not available or no image provided');
134
  }
135
 
136
+ try {
137
+ const output = await joyCaptionClient.predict("/stream_chat", [
138
+ state.userImage,
139
+ "Descriptive" as CaptionType,
140
+ "very long" as CaptionLength,
141
+ [], // extra_options
142
+ "", // name_input
143
+ "" // custom_prompt
144
+ ]);
145
+
146
+ const [prompt, caption] = output.data;
147
+ state.imageCaption = caption;
148
+ console.log('Caption generated:', caption);
149
+ } catch (error) {
150
+ handleAPIError(error);
151
+ }
152
  }
153
 
154
  async function generateMonsterConcept() {
 
162
 
163
  console.log('Generating monster concept with prompt:', conceptPrompt);
164
 
165
+ try {
166
+ const output = await rwkvClient.predict(0, [
167
+ conceptPrompt,
168
+ 300, // maxTokens
169
+ 0.7, // temperature
170
+ 0.8, // topP
171
+ 0.1, // presencePenalty
172
+ 0.1 // countPenalty
173
+ ]);
174
+
175
+ console.log('RWKV output:', output);
176
+ state.monsterConcept = output.data[0];
177
+ console.log('Monster concept generated:', state.monsterConcept);
178
+
179
+ if (!state.monsterConcept || state.monsterConcept.trim() === '') {
180
+ throw new Error('Failed to generate monster concept - received empty response');
181
+ }
182
+ } catch (error) {
183
+ handleAPIError(error);
184
  }
185
  }
186
 
 
195
 
196
  console.log('Generating image prompt from concept');
197
 
198
+ try {
199
+ const output = await rwkvClient.predict(0, [
200
+ promptGenerationPrompt,
201
+ 300, // maxTokens
202
+ 0.7, // temperature
203
+ 0.8, // topP
204
+ 0.1, // presencePenalty
205
+ 0.1 // countPenalty
206
+ ]);
207
+
208
+ console.log('Image prompt output:', output);
209
+ state.imagePrompt = output.data[0];
210
+ console.log('Image prompt generated:', state.imagePrompt);
211
+
212
+ if (!state.imagePrompt || state.imagePrompt.trim() === '') {
213
+ throw new Error('Failed to generate image prompt - received empty response');
214
+ }
215
+ } catch (error) {
216
+ handleAPIError(error);
217
  }
218
  }
219
 
 
224
  throw new Error('Image generation service not available or no prompt');
225
  }
226
 
227
+ try {
228
+ const output = await fluxClient.predict("/infer", [
229
+ `${state.imagePrompt}\nNow generate an Anime-style image of the monster in an idle pose with a white background. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
230
+ 0, // seed
231
+ true, // randomizeSeed
232
+ 1024, // width
233
+ 1024, // height
234
+ 4 // steps
235
+ ]);
236
+
237
+ const [image, usedSeed] = output.data;
238
+ let url: string | undefined;
239
+
240
+ if (typeof image === "string") url = image;
241
+ else if (image && image.url) url = image.url;
242
+ else if (image && image.path) url = image.path;
243
+
244
+ if (url) {
245
+ state.monsterImage = {
246
+ imageUrl: url,
247
+ seed: usedSeed,
248
+ prompt: state.imagePrompt
249
+ };
250
+ } else {
251
+ throw new Error('Failed to generate monster image');
252
+ }
253
+ } catch (error) {
254
+ handleAPIError(error);
255
  }
256
  }
257