Documentation Index Fetch the complete documentation index at: https://docs.edgespark.dev/llms.txt
Use this file to discover all available pages before exploring further.
Consistent error handling makes your API predictable for clients and easier to debug. This guide shows patterns that fit the current EdgeSpark scaffold and runtime SDK.
Return a standard error shape
import { db } from "edgespark" ;
import { auth } from "edgespark/http" ;
import { eq } from "drizzle-orm" ;
import { Hono } from "hono" ;
import { posts } from "@defs" ;
function err ( message : string , details ?: unknown ) {
return { error: message , ... ( details ? { details } : {}) };
}
const app = new Hono (). post ( "/api/posts" , async ( c ) => {
let body : { title ?: string ; content ?: string };
try {
body = await c . req . json ();
} catch {
return c . json ( err ( "Request body must be valid JSON" ), 400 );
}
if ( ! body . title || body . title . trim (). length === 0 ) {
return c . json ( err ( "Validation failed" , { field: "title" , issue: "required" }), 422 );
}
const [ post ] = await db
. insert ( posts )
. values ({ title: body . title . trim (), content: body . content ?? null , authorId: auth . user . id })
. returning ();
return c . json ( post , 201 );
});
export default app ;
Handle not found
import { db } from "edgespark" ;
import { eq } from "drizzle-orm" ;
import { Hono } from "hono" ;
import { posts } from "@defs" ;
const app = new Hono (). get ( "/api/posts/:id" , async ( c ) => {
const id = Number ( c . req . param ( "id" ));
if ( Number . isNaN ( id ) || id < 1 ) {
return c . json ({ error: "Invalid ID" }, 400 );
}
const [ post ] = await db . select (). from ( posts ). where ( eq ( posts . id , id ));
if ( ! post ) {
return c . json ({ error: "Post not found" }, 404 );
}
return c . json ( post );
});
export default app ;
Catch unexpected errors
import { db } from "edgespark" ;
import { eq } from "drizzle-orm" ;
import { Hono } from "hono" ;
import { posts } from "@defs" ;
const app = new Hono (). get ( "/api/posts/:id" , async ( c ) => {
try {
const id = Number ( c . req . param ( "id" ));
const [ post ] = await db . select (). from ( posts ). where ( eq ( posts . id , id ));
if ( ! post ) return c . json ({ error: "Not found" }, 404 );
return c . json ( post );
} catch ( error ) {
console . error ( "Failed to fetch post" , { id: c . req . param ( "id" ), error });
return c . json ({ error: "Internal server error" }, 500 );
}
});
export default app ;
Register global handlers
import { Hono } from "hono" ;
const app = new Hono ();
app . onError (( error , c ) => {
console . error ( "Unhandled error" , { path: c . req . path , error });
return c . json ({ error: "Internal server error" }, 500 );
});
app . notFound (( c ) => {
return c . json ({ error: "Not found" }, 404 );
});
export default app ;
Standard status codes
Situation Status Request body invalid JSON 400 Missing or invalid parameters 422 Not authenticated 401 Authenticated but not allowed 403 Resource not found 404 Success, returns body 200 Created successfully 201 Success, no body 204 Server error 500
The platform automatically returns 401 for unauthenticated requests to /api/* routes before your handler runs. You usually only need to handle 403 Forbidden yourself.
See also
Build a REST API A complete example with validation, auth, uploads, and error handling.
View logs Read runtime logs and exceptions from your deployed project.