
Research
TeamPCP Compromises Telnyx Python SDK to Deliver Credential-Stealing Malware
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.
okay-error
Advanced tools
A small opinionated library to bring Rust-like results idiomatically to TypeScript.
ok-errTyped, chain‑friendly, JSON‑safe Results for TypeScript
A small opinionated TypeScript library providing strongly-typed Result objects with chaining capabilities, inspired by Rust std::result.
Ok is { ok: true, value }, an Err is { ok: false, error }. Log it, persist it, send it over the wire.Result<T, E>), not thrown from the shadows. Rely on the type checker to ensure you handle every possible failure..annotate() method; walk the cause links later to see the full logical call stack.for (const v of ok(3)) … works, and helpers map, flatMap, or feel familiar to JS arrays.JSON.parse, call result(raw) to get the fluent API back.npm i ok-err
Here's how ok-err changes error handling from exceptions to data:
// Traditional approach with try-catch
try {
const user = getUserById(123);
const greeting = formatGreeting(user.name);
console.log(greeting);
} catch (error) {
// Error source and type information can be ambiguous
console.error('Something went wrong', error);
}
// Alternative approach with Result
import { ok, err, result } from 'ok-err';
// Define functions that return Result types
function getUserById(id: number) {
try {
if (id <= 0) {
return err('InvalidId')({ id });
}
// Simulating database lookup
const user = { id, name: 'Ada' };
return ok(user);
} catch (error) {
// Convert any unexpected errors
return err('DbError')({ cause: error });
}
}
// Using the Result-returning function
const userResult = getUserById(123);
if (!userResult.ok) {
// Typed error handling with precise context
console.error(`Database error: ${userResult.error.type}`);
return;
}
// Chain operations on successful results
const greeted = userResult
.map(u => u.name.toUpperCase()) // Ok<string>
.flatMap(name =>
name.startsWith('A')
? ok(`Hello ${name}!`) // Return Ok for success
: err('NameTooShort')({ min: 1 }) // Return Err for failure
)
.or('Hi stranger!'); // Use fallback if any step failed
console.log(greeted); // "Hello ADA!"
Context propagation allows you to wrap lower-level errors with higher-level context as they move up through your application's layers so you know where the error occurred.
function readConfig(): Result<string, ConfigErr> { … }
function boot(): Result<void, BootErr> {
const cfg = readConfig();
if (!cfg.ok) {
// Add higher-level context while preserving the original error
return cfg.annotate('BootConfig', { phase: 'init' });
}
return ok(undefined);
}
.annotate() creates a new error that wraps the original error:
cause property of the new errorThis creates a discoverable, traceable error chain that's invaluable for debugging:
Err {
type: "BootConfig",
phase: "init",
cause: Err {
type: "ConfigFileMissing",
path: "/etc/app.json",
cause: Err { type: "IO", errno: "ENOENT" }
}
}
ok-err can be used with async code to handle errors as data:
import { result } from 'ok-err';
// Wrap fetch with Result to handle both network and parsing errors
async function fetchUserData(userId: string) {
// First, handle the network request
const response = await result(fetch(`/api/users/${userId}`));
if (!response.ok) {
return response.annotate('NetworkError', { userId });
}
// Then handle the JSON parsing
const data = await result(response.value.json());
if (!data.ok) {
return data.annotate('ParseError', { userId });
}
// Validate the data
if (!data.value.name) {
return err('ValidationError')({
userId,
message: 'User name is required'
});
}
return ok(data.value);
}
// Usage with proper error handling
async function displayUserProfile(userId: string) {
const userData = await fetchUserData(userId);
if (!userData.ok) {
// Each error has context about where it happened
switch (userData.error.type) {
case 'NetworkError':
console.error('Connection failed');
break;
case 'ParseError':
console.error('Invalid response format');
break;
case 'ValidationError':
console.error(userData.error.message);
break;
}
return;
}
// Work with the data safely
console.log(`Welcome, ${userData.value.name}!`);
}
| ✔ | Feature | Example |
|---|---|---|
| Typed constructors | err('Timeout')({ ms: 2000 }) | |
map, flatMap, or | ok(1).map(x=>x+1).flatMap(fn).or(0) | |
| Works with Promise | await result(fetch(url)) | |
| Cause‑chain + optional stack frame | err(...).annotate('DB', {...}) | |
| JSON serialisable & iterable | JSON.stringify(err('X')()), [...ok(7)] | |
| Re‑hydrate after JSON | const live = result(JSON.parse(raw)) |
| function | purpose |
|---|---|
ok(value) | success result |
err(kind)(payload?) | typed error + trace |
errAny(value) | error without a discriminant / trace |
result(x) | wrap a sync fn, a Promise, or re‑hydrate a raw object |
Ok & Err)| method | on Ok | on Err |
|---|---|---|
map(fn) | transform value | no‑op |
mapErr(fn) | no‑op | transform error |
flatMap(fn) | chain another Result | propagate error |
unwrap() | get value | throw error |
or(fallback) | value | fallback |
[Symbol.iterator]() | yields value | yields nothing |
.annotate(kind, payload?) – add context + cause (on Err instances only)type Result<T, E = unknown> = Ok<T> | Err<E>;
const errOut = err('DbConn')({ host: 'db.local' });
const raw = JSON.stringify(errOut);
const back = result(JSON.parse(raw)); // re‑hydrated
for (const v of back) console.log(v); // nothing, because Err
// Create an error chain
const ioError = err('IO')({ errno: 'ENOENT' });
const configError = ioError.annotate('ConfigFileMissing', { path: '/etc/app.json' });
const bootError = configError.annotate('BootConfig', { phase: 'init' });
// Now you can navigate the error chain
console.log(bootError.error.type); // 'BootConfig'
console.log(bootError.error.cause.type); // 'ConfigFileMissing'
MIT
FAQs
A small opinionated library to bring Rust-like results idiomatically to TypeScript.
The npm package okay-error receives a total of 7,283 weekly downloads. As such, okay-error popularity was classified as popular.
We found that okay-error demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.

Security News
/Research
Widespread GitHub phishing campaign uses fake Visual Studio Code security alerts in Discussions to trick developers into visiting malicious website.