Edge Cases and Special Values
Learn how go-errors handles complex JavaScript values and edge cases
Complex Objects
Nested Objects
import { goSync } from 'go-errors';
// Handling deeply nested objects
let [result, err] = goSync(() => {
throw { nested: { deep: { value: 42 } } };
});
// err will be an Error with message: '{"nested":{"deep":{"value":42}}}'
// Handling arrays
let [result, err] = goSync(() => {
throw [1, 2, 3];
});
// err will be an Error with message: '[1,2,3]'
// Mixed complex objects
let [result, err] = goSync(() => {
throw { arr: [1, { x: 2 }], obj: { y: [3, 4] } };
});
// err will be an Error with message: '{"arr":[1,{"x":2}],"obj":{"y":[3,4]}}'
Circular References
let circular: any = { foo: "bar" };
circular.self = circular;
let [result, err] = goSync(() => {
throw circular;
});
// err will be an Error with message: "JSON.stringify cannot serialize cyclic structures."
Special JavaScript Values
Symbol Handling
let sym = Symbol('test');
let [result, err] = goSync(() => {
throw sym;
});
// err will be an Error with message: 'Symbol(test)'
BigInt Support
let [result, err] = goSync(() => {
throw BigInt(9007199254740991);
});
// err will be an Error with message: '9007199254740991'
Function Objects
function testFn() { return 42; }
let [result, err] = goSync(() => {
throw testFn;
});
// err will be an Error containing function representation
Date Objects
let date = new Date('2024-01-01');
let [result, err] = goSync(() => {
throw date;
});
// err will be an Error with stringified date
RegExp Objects
let regex = /test/gi;
let [result, err] = goSync(() => {
throw regex;
});
// err will be an Error with message: '/test/gi'
Error Stack Preservation
let [result, err] = goSync(() => {
throw new Error('test');
});
// err.stack will contain the full stack trace
// err.stack will include 'test' and file information
Custom Error Properties
class CustomError extends Error {
constructor(public code: number, message: string) {
super(message);
this.name = 'CustomError';
}
}
let [result, err] = goSync(() => {
throw new CustomError(500, 'test');
});
// err will be instanceof CustomError
// err.code will be 500
// err.name will be 'CustomError'
Nested Errors
let [result, err] = goSync(() => {
const e = new Error('outer');
e.cause = new Error('inner');
throw e;
});
// err.message will be 'outer'
// err.cause.message will be 'inner'
Special Return Values
Undefined and Null
// Handling undefined
let [result, err] = await goFetch<undefined>('/api/empty');
// result will be undefined
// err will be null
// Handling null
let [result, err] = await goFetch<null>('/api/null');
// result will be null
// err will be null
Empty String and Zero Values
// Empty string
let [result, err] = goSync(() => "");
// result will be ""
// err will be null
// Zero
let [result, err] = goSync(() => 0);
// result will be 0
// err will be null
// False
let [result, err] = goSync(() => false);
// result will be false
// err will be null
HTTP Edge Cases
// Empty response
let [data, err] = await goFetch('/api/empty');
// data will be undefined or null depending on response
// Non-JSON response
let [text, err] = await goFetch<string>('/api/text', {
responseTransformer: async (response) => {
if (response instanceof Response) {
return response.text();
}
return String(response);
}
});
// Binary response
let [blob, err] = await goFetch<Blob>('/api/binary', {
responseTransformer: async (response) => {
if (response instanceof Response) {
return response.blob();
}
throw new Error('Expected binary response');
}
});
Best Practices
-
Handle Circular References
// ✅ Good: Check for circular structures function safeStringify(obj: unknown): string { try { return JSON.stringify(obj); } catch (e) { if (e instanceof Error && e.message.includes('circular')) { return 'Circular structure detected'; } throw e; } }
-
Preserve Error Properties
// ✅ Good: Preserve custom properties class AppError extends Error { constructor(message: string, public details: Record<string, unknown>) { super(message); Object.setPrototypeOf(this, AppError.prototype); } }
-
Type Safety with Special Values
// ✅ Good: Type-safe handling function processValue<T>(value: T | undefined | null) { let [result, err] = goSync(() => { if (value === undefined) return 'undefined'; if (value === null) return 'null'; return String(value); }); return [result, err] as const; }