Skip to content
字数
556 字
阅读时间
4 分钟

Go

go
f, err := os.Open(“filename.ext”)
if err != nil {
  log.Fatal(err)
}
// do something with the open *File f

Rust

rust
let greeting_file_result = File::open(“hello.txt”);
let greeting_file = match greeting_file_result {
  Ok(file) => file,
  Err(error) => panic!("Problem opening the file: {:?}", error),
};

TypeScript

ts
export type Safe<T> =
  | {
    success: true;
    data: T;
  }
  | {
    success: false;
    error: string;
  };

export function safe<T>(promise: Promise<T>, err?: string): Promise<Safe<T>>;
export function safe<T>(func: () => T, err?: string): Safe<T>;
export function safe<T>(
  promiseOrFunc: Promise<T> | (() => T),
  err?: string,
): Promise<Safe<T>> | Safe<T> {
  if (promiseOrFunc instanceof Promise) {
    return safeAsync(promiseOrFunc, err);
  }
  return safeSync(promiseOrFunc, err);
}

async function safeAsync<T>(
  promise: Promise<T>, 
  err?: string
): Promise<Safe<T>> {
  try {
    const data = await promise;
    return { data, success: true };
  } catch (e) {
    console.error(e);
    if (err !== undefined) {
      return { success: false, error: err };
    }
    if (e instanceof Error) {
      return { success: false, error: e.message };
    }
    return { success: false, error: "Something went wrong" };
  }
}

function safeSync<T>(
  func: () => T, 
  err?: string
): Safe<T> {
  try {
    const data = func();
    return { data, success: true };
  } catch (e) {
    console.error(e);
    if (err !== undefined) {
      return { success: false, error: err };
    }
    if (e instanceof Error) {
      return { success: false, error: e.message };
    }
    return { success: false, error: "Something went wrong" };
  }
}

case 用例

ts
// Old one (16 lines):

try {
  const request = { name: “test”, value: 2n };
  const body = JSON.stringify(request);
  const response = await fetch("https://example.com", {
    method: “POST”,
    body,
  });
  if (!response.ok) {
    // handle network error
    return;
  }
  // handle response
} catch (e) {
  // handle error
  return;
}

// New one (20 lines):
const request = { name: “test”, value: 2n };
const body = safe(
  () => JSON.stringify(request),
Failed to serialize request”,
);
if (!body.success) {
  // handle error (body.error)
  return;
}
const response = await safe(
  fetch("https://example.com", {
    method: “POST”,
    body: body.data,
  }),
);
if (!response.success) {
  // handle error (response.error)
  return;
}
if (!response.data.ok) {
  // handle network error
  return;
}
// handle response (body.data)
  • 没有 try/catch
  • 处理发生的每一个错误
  • 可以为特定函数指定错误消息
  • 有一个很好的自上而下的逻辑,所有的错误在上面,然后只有在底部的响应

SvelteKit

ts
// FormAction
export const actions = {
  createEmail: async ({ locals, request }) => {
    const end = perf(“CreateEmail”);
    const form = await safe(request.formData());
    if (!form.success) {
      return fail(400, { error: form.error });
    }
    const schema = z
      .object({
        emailTo: z.string().email(),
        emailName: z.string().min(1),
        emailSubject: z.string().min(1),
        emailHtml: z.string().min(1),
      })
    .safeParse({
      emailTo: form.data.get("emailTo"),
      emailName: form.data.get("emailName"),
      emailSubject: form.data.get("emailSubject"),
      emailHtml: form.data.get("emailHtml"),
    });
    if (!schema.success) {
      console.error(schema.error.flatten());
      return fail(400, { form: schema.error.flatten().fieldErrors });
    }
    const metadata = createMetadata(URI_GRPC, locals.user.key)
    if (!metadata.success) {
      return fail(400, { error: metadata.error });
    }
    const response = await new Promise<Safe<Email__Output>>((res) => {
      usersClient.createEmail(schema.data, metadata.data, grpcSafe(res));
    });
    if (!response.success) {
      return fail(400, { error: response.error });
    }
    end();
    return {
      email: response.data,
    };
  },
} satisfies Actions;

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写