mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-15 02:15:14 +00:00
fix(login): improve error classification (#11926)
Closes #11923 # Which Problems Are Solved Client-side gRPC errors (e.g. NotFound, InvalidArgument, PermissionDenied) were being surfaced as HTTP 500 Internal Server Errors, causing false SRE alerts and poor UI feedback. # How the Problems Are Solved - New transport interceptor (`error-classification.ts`): Automatically enriches every ConnectError with httpStatus and isUserError metadata via a `ClassifiedConnectError` wrapper - Route handler protection (`route.ts`, `flow-initiation.ts`): Catches classified errors from `getAuthRequest` / `getSAMLRequest` and returns correct HTTP status codes instead of 500 - Type safety: Replaced all magic number error.code === 9 checks with typed Code.FailedPrecondition + instanceof ConnectError across `oidc.ts`, `saml.ts`, `password.ts`, `zitadel.ts` - Classification-aware logging (`session.ts`): Client/user errors log at warn level, server errors at error level - Observability (`otel.ts`): Spans now include error.is_user_error and http.status_code attributes for alert filtering # Additional Changes Gitignore `next-env.d.ts`: This file is auto-generated by Next.js on every next dev and next build invocation. The two modes write slightly different import paths (.next/dev/types/ vs .next/types/), which causes git diff --exit-code to fail in CI whenever a developer runs next dev locally before committing. Since Next.js regenerates it automatically, there's no need to track it --------- Co-authored-by: Ramon <[email protected]> Co-authored-by: Copilot <[email protected]>
This commit is contained in:
co-authored by
Ramon
Copilot
parent
8e41d288ff
commit
ff4aae7b3f
@@ -34,8 +34,9 @@ import { getTranslations } from "next-intl/server";
|
||||
import { getUserAgent } from "./fingerprint";
|
||||
import { createLogger } from "./logger";
|
||||
|
||||
import { errorClassificationInterceptor } from "@/lib/grpc/interceptors/error-classification";
|
||||
import { otelGrpcInterceptor } from "@/lib/grpc/interceptors/otel";
|
||||
import { Interceptor } from "@connectrpc/connect";
|
||||
import { Code, ConnectError, Interceptor } from "@connectrpc/connect";
|
||||
import { createServiceForHost } from "./service";
|
||||
|
||||
const logger = createLogger("zitadel");
|
||||
@@ -1154,7 +1155,7 @@ export async function setUserPassword({
|
||||
|
||||
return userService.setPassword(payload, {}).catch((error) => {
|
||||
// throw error if failed precondition (ex. User is not yet initialized)
|
||||
if (error.code === 9 && error.message) {
|
||||
if (error instanceof ConnectError && error.code === Code.FailedPrecondition && error.message) {
|
||||
return { error: error.message };
|
||||
} else {
|
||||
throw error;
|
||||
@@ -1378,6 +1379,6 @@ export function createServerTransport(token: string, serviceConfig: ServiceConfi
|
||||
return createConnectTransport({
|
||||
httpVersion: "1.1",
|
||||
baseUrl: serviceConfig.baseUrl,
|
||||
interceptors: [otelGrpcInterceptor, authorizationInterceptor, headerInterceptor],
|
||||
interceptors: [otelGrpcInterceptor, errorClassificationInterceptor, authorizationInterceptor, headerInterceptor],
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user