Skip to content

Commit 80f34b5

Browse files
committed
docs: update README for v2
Defensive programming framing, ESM/CJS/browser examples. Error.cause docs, rewritten EidPreconditions section. Drop Bower, update badges to GitHub Actions. Assisted-by: 🤖 claude-opus-4-6@default
1 parent 6b883c2 commit 80f34b5

1 file changed

Lines changed: 122 additions & 100 deletions

File tree

‎README.md‎

Lines changed: 122 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,207 @@
1-
# EID Runtime Exceptions and Utilities for Javascript
1+
# EID Runtime Exceptions and Utilities for JavaScript/TypeScript
22

3-
[![Build Status](https://travis-ci.org/wavesoftware/javascript-eid-exceptions.svg?branch=master)](https://travis-ci.org/wavesoftware/javascript-eid-exceptions) [![Coverage Status](https://coveralls.io/repos/wavesoftware/javascript-eid-exceptions/badge.svg?branch=master&service=github)](https://coveralls.io/github/wavesoftware/javascript-eid-exceptions?branch=master) [![npm](https://img.shields.io/npm/v/eid.js.svg)](https://www.npmjs.com/package/eid.js) [![Bower](https://img.shields.io/bower/v/eid.js.svg)]()
3+
[![CI](https://github.com/wavesoftware/javascript-eid-exceptions/actions/workflows/ci.yml/badge.svg)](https://github.com/wavesoftware/javascript-eid-exceptions/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/eid.js.svg)](https://www.npmjs.com/package/eid.js)
44

5-
This small library holds a set of exceptions and utilities that implements idea of fast, reusable, error codes that can be simply thrown fast in case of unpredictable and unrecoverable application failure. It is meant to be used for application bugs.
5+
A small, zero-dependency library for [defensive programming](https://en.wikipedia.org/wiki/Defensive_programming) in JavaScript and TypeScript. It provides reusable Exception IDs (EIDs), precondition checks, and standardized error handling for fail-fast detection of programming errors.
66

7-
## Idea
7+
Instead of writing ad-hoc validation with generic `Error` messages, you assign a unique, permanent ID to each check site. When a bug reaches production, the ID links the error page (or log entry) directly to the line of code that failed.
88

9-
The idea is to use a set of simple runtime exceptions. They should always take the Exception ID (Eid) object in the making. This eid object will then be reported when displaying or logging that exception. It can also be viewed on the professional fatal error window of the application as a bug reference. EidRuntimeExceptions contains also additional unique ID to distinguish each single exception from others with same Eid. This approach simplifies the management of exceptions in the application and allows developers to focus on functionalities rather than coming up with the correct statement for the exception.
9+
## How it works
1010

11-
This approach is best to use with tools and plugins like:
11+
Every exception takes an `Eid` object that combines two identifiers:
1212

13-
* [EidGenerator for Netbeans IDE](http://plugins.netbeans.org/plugin/53137/exception-id-eid-generator)
14-
* [Generating Exception Id number in Intellij IDEA with Live Templates](https://github.com/wavesoftware/java-eid-exceptions/wiki/Generating%20Exception%20Id%20number%20in%20Intellij%20IDEA%20with%20Live%20Templates)
13+
- A **static ID** (e.g. `"20260714:120000"`) -- a permanent label inserted by the developer at the throw site.
14+
- A **unique ID** (e.g. `<a3f7x1>`) -- generated at runtime to distinguish individual occurrences.
1515

16-
Example:
16+
When the exception is logged or displayed on an error page, both IDs appear together. Support teams search by the static ID to find the code path, and by the unique ID to pinpoint the exact occurrence.
1717

18-
```js
19-
var cause = 'A extra message';
20-
throw new EidIllegalStateException("20150721:100554", cause);
18+
```typescript
19+
import { EidIllegalStateException } from "eid.js";
20+
21+
throw new EidIllegalStateException("20260714:120000", "An extra message");
2122
```
2223

23-
Example log:
24+
Output:
2425

2526
```
26-
ERROR 2016-01-11T22:48:42.445 EidIllegalStateException: [20150721:100554]<rww5y3> A extra message - Error
27-
at http://localhost:3000/browser/toplevel/eid.min.js:1:3959
28-
at Object.i.3.../eid (http://localhost:3000/browser/toplevel/eid.min.js:1:4211)
29-
at r (http://localhost:3000/browser/toplevel/eid.min.js:1:254)
30-
at http://localhost:3000/browser/toplevel/eid.min.js:1:305
31-
at http://localhost:3000/browser/toplevel/eid.min.js:1:536
32-
at Object.i.1.../../lib/eid (http://localhost:3000/browser/toplevel/eid.min.js:1:974)
33-
at r (http://localhost:3000/browser/toplevel/eid.min.js:1:254)
34-
at t (http://localhost:3000/browser/toplevel/eid.min.js:1:421)
35-
at http://localhost:3000/browser/toplevel/eid.min.js:1:438
27+
EidIllegalStateException: [20260714:120000]<a3f7x1> An extra message
28+
at Object.<anonymous> (/app/src/service.ts:42:11)
3629
```
3730

31+
Static IDs can be generated using [Live Templates in IntelliJ IDEA](https://github.com/wavesoftware/java-eid-exceptions/wiki/Generating%20Exception%20Id%20number%20in%20Intellij%20IDEA%20with%20Live%20Templates).
3832

39-
## Caution
33+
## Intended use
4034

41-
This classes shouldn't be used in any public API or library. It is designed to be used for in-house development of end user applications which will report bugs in standardized error pages or post them to issue tracker.
35+
This library is not intended for public APIs or shared libraries. It is designed for in-house, end-user applications that report bugs through standardized error pages or issue trackers.
4236

43-
## NPM
37+
## Installation
4438

4539
```bash
46-
npm install eid.js --save
40+
npm install eid.js
4741
```
4842

49-
## Bower
43+
### ESM (recommended)
5044

51-
```bash
52-
bower install eid.js --save
45+
```typescript
46+
import { Eid, EidPreconditions, EidIllegalStateException } from "eid.js";
5347
```
5448

55-
### `EidPreconditions` class
49+
### CommonJS
50+
51+
```javascript
52+
const { Eid, EidPreconditions, EidIllegalStateException } = require("eid.js");
53+
```
5654

57-
#### General use
55+
### Browser (IIFE)
5856

59-
`EidPreconditions` class consists static methods that help to use Eid in a method or constructor. This is solely for convenience purposes. Use them to check whether method or constructor was invoked correctly (whether its preconditions have been met). These methods generally accept a `boolean` expression which is expected to be `true` (or in the case of `checkNotNull`, an object reference which is expected to be non-null). When `false` (or `null`) is passed instead, the `EidPreconditions` method throws an unchecked exception, which helps the calling method communicate to its caller that that caller has made a mistake.
57+
```html
58+
<script src="https://unpkg.com/eid.js/dist/index.global.js"></script>
59+
<script>
60+
const { Eid, EidPreconditions } = window.Eid;
61+
</script>
62+
```
6063

61-
Each method accepts a EID string or Eid object, which is designed to ease of use and provide strict ID for given exception usage. This approach speed up development of large application and helps support teams by giving both static and random ID for each possible bug that could occur.
64+
## Error cause support
6265

63-
Each example uses static import:
66+
All Eid exceptions support the standard ES2022 `Error.cause` property, preserving the original error and its full stack trace:
6467

65-
```js
66-
// nodejs
67-
var EidPreconditions = require('eid.js').preconditions;
68+
```typescript
69+
import { EidRuntimeException } from "eid.js";
6870

69-
// browser using bower using toplevel version
70-
var EidPreconditions = window.Eid.preconditions;
71+
try {
72+
riskyOperation();
73+
} catch (err) {
74+
throw new EidRuntimeException("20260714:120000", "operation failed", err);
75+
// The original error is available via .cause
76+
}
7177
```
7278

73-
#### `checkArgument` method
79+
`tryToExecute` chains the caught error as `cause` automatically:
7480

75-
`checkArgument` method should be used to check argument of the method, and validate it in technical terms (not business terms).
81+
```typescript
82+
import { EidPreconditions } from "eid.js";
7683

77-
Example:
78-
79-
```js
80-
// [..]
81-
function sqrt(value) {
82-
checkArgument(value >= 0.0, "20150718:012333");
83-
// if ok, calculate the square root
84-
}
84+
const result = EidPreconditions.tryToExecute(() => {
85+
return JSON.parse(untrustedInput);
86+
}, "20260714:120100");
87+
// If JSON.parse throws, the SyntaxError is available via .cause
8588
```
8689

87-
In this example, `checkArgument` throws an `EidIllegalArgumentException` to indicate that developer made an error in its call to `sqrt`.
90+
## `EidPreconditions`
8891

89-
#### `checkState` method
92+
A collection of static methods for validating preconditions. Each method accepts an EID string (or an `Eid` object) and throws a typed Eid exception when the check fails.
9093

91-
`checkState` method should be used to check state of the class in given moment, and validate it in technical terms (not business terms).
94+
### `checkArgument`
9295

93-
Example:
96+
Validates a method argument in technical terms (not business rules).
9497

95-
```js
96-
checkState(a >= 3.14 && b < 0., "20150721:115016");
98+
```typescript
99+
import { EidPreconditions } from "eid.js";
100+
101+
function sqrt(value: number): number {
102+
EidPreconditions.checkArgument(value >= 0.0, "20150718:012333");
103+
return Math.sqrt(value);
104+
}
97105
```
98106

99-
#### `checkNotNull` method
107+
Throws `EidIllegalArgumentException` if `value` is negative.
100108

101-
`checkNotNull` method should be used to check if given non null argument is actually `null`
109+
### `checkState`
102110

103-
Example:
111+
Validates the internal state of an object at a given moment.
104112

105-
```js
106-
var nonNullUserName = checkNotNull(userName, "20150721:115515");
113+
```typescript
114+
EidPreconditions.checkState(a >= 3.14 && b < 0, "20150721:115016");
107115
```
108116

109-
#### `checkElementIndex` method
117+
### `checkNotNull`
110118

111-
`checkElementIndex` method can be used to test parameters of an array, before being used
119+
Ensures that a reference is not `null`.
112120

113-
```js
114-
checkElementIndex(index, list.length, "20150721:115749");
121+
```typescript
122+
const nonNullUserName = EidPreconditions.checkNotNull(userName, "20150721:115515");
115123
```
116124

117-
#### Formatted message support
125+
### `checkElementIndex`
126+
127+
Validates that an index is within bounds of an array or list.
128+
129+
```typescript
130+
EidPreconditions.checkElementIndex(index, list.length, "20150721:115749");
131+
```
118132

119-
There have been added additional `message` to method descriptors for `checkArgument`, `checkState`, `checkNotNull` and `checkElementIndex` method. Those method's parameter can sometimes be used to pass additional information to exceptions that will be displayed in log files.
133+
### Optional message
120134

121-
For example:
135+
All check methods accept an optional `message` parameter with additional context for the exception:
122136

123-
```js
124-
checkState(transation.isValid(), "20151119:120238", "Invalid transaction: " + transaction);
137+
```typescript
138+
EidPreconditions.checkState(
139+
transaction.isValid(),
140+
"20151119:120238",
141+
`Invalid transaction: ${transaction}`
142+
);
125143
```
126144

127-
Will produce output similar to;
145+
Output:
128146

129147
```
130-
EidIllegalStateException: [20151119:120238]<xf4j1l> => Invalid transaction: <Transaction id=null, buyer=null, products=[]>
148+
EidIllegalStateException: [20151119:120238]<xf4j1l> Invalid transaction: <Transaction id=null, buyer=null, products=[]>
131149
```
132150

133-
#### Functional try to execute blocks
151+
### `tryToExecute`
134152

135-
You can use functional blocks to handle operations, that are intended to operate properly. This approach simplify the code and makes it more readable. It's also good way to deal with untested, uncovered `catch` blocks. It's easy and gives developers nice way of dealing with countless operations that suppose to work as intended.
153+
Wraps a block of code that is expected to succeed. If it throws, the error is re-thrown as an `EidRuntimeException` with the original error preserved as `cause`.
136154

137-
Example:
155+
```typescript
156+
import { EidPreconditions } from "eid.js";
157+
import { readFileSync } from "node:fs";
138158

139-
```js
140-
var content = EidPreconditions.tryToExecute(function() {
141-
var fs = require('fs');
142-
return fs.readFileSync('project.properties');
159+
const content = EidPreconditions.tryToExecute(() => {
160+
return readFileSync("project.properties", "utf-8");
143161
}, "20150718:121521");
144162
```
145163

146-
#### Logging
164+
### Logging
165+
166+
The `Eid` object provides a `makeLogMessage` method for structured log output. Use `%s` as a format specifier:
147167

148-
Eid object can also be useful in logging. That are `makeLogMessage` method provided to do that. Message formatting is done using equivalent of Java's `String.format(String, Object[])` method.
149-
For example:
168+
```typescript
169+
import { Eid } from "eid.js";
150170

151-
```js
152171
log.debug(new Eid("20151119:121814").makeLogMessage("REST request received: %s", request));
153172
```
154173

155-
will unfold to something similar to:
174+
Output:
156175

157176
```
158-
2017-01-08T16:45:34,334 DEBUG [20151119:121814]<d1afca> REST request received: <RestRequest user=<User id=345> flow=ShowLastTransactions step=Confirm>
177+
[20151119:121814]<d1afca> => REST request received: <RestRequest user=<User id=345>>
159178
```
160179

161-
###Contributing
180+
## Contributing
162181

163182
Contributions are welcome!
164183

165-
To contribute, follow the standard [git flow](http://danielkummer.github.io/git-flow-cheatsheet/) of:
184+
1. Fork the repository
185+
2. Create a feature branch (`git checkout -b feature/my-new-feature`)
186+
3. Commit your changes (`git commit -am 'Add some feature'`)
187+
4. Push to the branch (`git push origin feature/my-new-feature`)
188+
5. Open a Pull Request
166189

167-
1. Fork it
168-
1. Create your feature branch (`git checkout -b feature/my-new-feature`)
169-
1. Commit your changes (`git commit -am 'Add some feature'`)
170-
1. Push to the branch (`git push origin feature/my-new-feature`)
171-
1. Create new Pull Request
172-
173-
Even if you can't contribute code, if you have an idea for an improvement please open an [issue](https://github.com/wavesoftware/javascript-eid-exceptions/issues).
190+
If you have an idea for an improvement, please open an [issue](https://github.com/wavesoftware/javascript-eid-exceptions/issues).
174191

175192
## Requirements
176193

177-
* NodeJS >= 0.10
178-
* Any modern browser, supported by browserify.
179-
194+
* Node.js >= 20
195+
* TypeScript >= 5.0 (optional, types are included)
180196

181-
### Releases
197+
## Releases
182198

199+
- 2.0.0
200+
- Full rewrite to TypeScript
201+
- ESM + CommonJS + IIFE browser bundle
202+
- ES2022 `Error.cause` support
203+
- Vitest test suite, Biome linting, GitHub Actions CI
204+
- Dropped: Bower, Gulp, Travis CI, Node < 20
183205
- 1.0.0
184-
- initial release
185-
- library ported from Java version
206+
- Initial release
207+
- Library ported from Java version

0 commit comments

Comments
 (0)