
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
atraceApplication development and telemetry toolkit.
pinoGood error handling is a prerequisite for good logging. To help with this,
atrace provides two simple but powerful building blocks.
The libraryErrorClass function generates a base error class which provides:
import {libraryErrorClass} from 'atrace';
// Flexible error class, allowing arbitrary strings as codes.
const GenericError = libraryErrorClass('my-lib');
const err1 = new GenericError('SOMETHING_FAILED'); // OK.
// Strongly typed error codes.
type ErrorID = 'BAR_MISSING' | 'BAZ_BROKEN';
const SpecificError = libraryErrorClass<ErrorID>('my-lib');
const err2 = new SpecificError('BAR_MISSING'); // OK.
const err3 = new SpecificError('SOMETHING_FAILED'); // Fails (unknown ID).
// For even more customization, you can extend the class as usual.
class CustomError extends libraryErrorClass<ErrorID>('my-lib') {
constructor(id: ErrorID, someData: number) {
super(id, {values: {someData}});
}
// ...
}
const err4 = new CustomError('BAZ_BROKEN', 123);
Beyond the capabilities offered by library errors, applications typically also
need the ability to surface statuses back to the client. As a convenience, the
standardError function is also available to create application errors from a
status.
import {applicationErrorFactory, standardError} from 'atrace';
// For large applications, prefer to create your own error codes:
const newError = applicationErrorFactory('bar', {
'BAD_TOGGLE': 'INVALID_ARGUMENT',
'BOOM': 'INTERNAL',
});
const err1 = newError('BAD_TOGGLE'); // Error with invalid argument status.
// For simple use-cases, you can use the convenience standard errors.
const err2 = standardError('NOT_FOUND');
import {
intSetting,
invalidSource,
settingsProvider,
stringSetting,
} from 'atrace';
const settings = settingsProvider((env) => ({
port: intSetting(env.PORT ?? 8080), // Integer value
auth: { // Hierarchical settings
clientID: stringSetting(env.CLIENT_ID ?? 'my-client'), // String value
clientSecret: stringSetting({
source: env.CLIENT_SECRET ?? invalidSource, // Required string value
sensitive: true, // Redact field from parsed sources
}),
},
tag: stringSetting(env.TAG), // Optional string value
}));
const val = settings(); // Parsed values
Importantly, val's type will automatically be inferred as:
{
readonly port: number;
readonly auth: {
readonly clientID: string;
readonly clientSecret: string;
}
readonly tag: string | undefined;
}
If CLIENT_SECRET wasn't defined in the environment, the config provider will
throw an informative exception. To test different setting values without needing
mocks, pass in a custom environment when calling the config provider.
const val = settings({
CLIENT_ID: 'test-id',
CLIENT_SECRET: 'test-secret',
});
We provide a convenience factory builder for types which do not need any non-standard creation arguments.
import {simpleSettingFactory} from 'atrace';
// A setting which will have values inferred as `Date`s.
const dateSetting = simpleSettingFactory((s): Date => new Date(s));
If additional arguments are desired, it's always possible--just more verbose--to use the underlying setting factory directly. For example, here's one way to implement an enum setting:
import {newSetting, Setting, SettingParams, SettingSource} from 'atrace';
/** Enum setting creation parameters. */
export interface EnumSettingParams<E extends string, S>
extends SettingParams<S> {
/** Allowed enum values. */
readonly symbols: ReadonlyArray<E>;
}
/** Creates a new enum setting. */
export function enumSetting<E extends string, S extends SettingSource>(
params: EnumSettingParams<E, S>
): Setting<S, E> {
return newSetting(params, (s): any => {
if (!~params.symbols.indexOf(s as any)) {
throw new Error('Invalid enum value');
}
return s;
});
}
In production code, we recommend using modular configuration types. Performing
post-processing on setting values is easy with a settingsManager:
// src/config.ts
import {settingsManager} from 'atrace';
// First the (private) underlying settings resource manager.
const withSettings = settingsManager((env) => ({/* ... */}));
// Then the (public) configuration types. These can be different from the raw
// settings for example discriminated unions are often handy. These are meant
// to be used everywhere in the application. Smaller, more specific, types will
// make testing easier and increase modularity.
export interface ModuleAConfig {/* ... */}
export interface ModuleBConfig {/* ... */}
export interface Config {
readonly moduleA: ModuleAConfig;
readonly moduleB: ModuleBConfig;
// ...
}
// Now the (public, though not meant for use everywhere - see below)
// configuration factory. This function should only be imported in the
// application's entry point and this module's unit-tests. Other modules should
// accept already instantiated configuration types, making testing much easier
// and dependencies explicit.
export const config = withSettings((val) => {
// Transform the setting values into the public configuration types...
return {/* ... */};
});
// test/config.test.ts
import * as sut from '../src/config';
// Within a test...
const env = {/* ... */}; // Test environment.
expect(config(env)).toEqual(/* ... */); // Expected config for the environment.
FAQs
Application tracing
We found that atrace demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.