or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

autorest-processing.mdconfiguration.mddocument-processing.mdindex.mdmessage-handling.md

message-handling.mddocs/

0

# Message Handling

1

2

Comprehensive message and event system for progress reporting, error handling, and structured logging throughout the AutoRest generation process. The message system provides detailed feedback about processing stages, validation results, and any issues encountered.

3

4

## Capabilities

5

6

### Message Interface

7

8

Core message structure for all communication within AutoRest.

9

10

```typescript { .api }

11

/**

12

* Message structure for AutoRest communication

13

* Represents all types of messages generated during processing

14

*/

15

interface Message {

16

/** Message severity and type */

17

Channel: Channel;

18

19

/** Message text content */

20

Text: string;

21

22

/** Optional message key for categorization */

23

Key?: Iterable<string>;

24

25

/** Additional message details */

26

Details?: any;

27

28

/** Source locations where message originated */

29

Source?: Array<SourceLocation>;

30

31

/** Source ranges for precise location */

32

Range?: Iterable<Range>;

33

34

/** Plugin that generated the message */

35

Plugin?: string;

36

37

/** Pre-formatted message text */

38

FormattedMessage?: string;

39

}

40

```

41

42

### Channel Enumeration

43

44

Message severity and type classification system.

45

46

```typescript { .api }

47

/**

48

* Message channel enumeration

49

* Defines the severity and type of messages

50

*/

51

enum Channel {

52

/** Information is considered the mildest of responses; not necessarily actionable */

53

Information = "information",

54

55

/** Warnings are considered important for best practices, but not catastrophic */

56

Warning = "warning",

57

58

/** Errors are considered blocking issues that block successful operation */

59

Error = "error",

60

61

/** Debug messages are designed for developer communication of internal details */

62

Debug = "debug",

63

64

/** Verbose messages give the user additional clarity on the process */

65

Verbose = "verbose",

66

67

/** Catastrophic failure, likely abending the process */

68

Fatal = "fatal",

69

70

/** Hint messages offer guidance or support without forcing action */

71

Hint = "hint",

72

73

/** File represents a file output from an extension */

74

File = "file",

75

76

/** Configuration represents an update/creation of a configuration file */

77

Configuration = "configuration"

78

}

79

```

80

81

### Source Location Types

82

83

Precise location information for messages and errors.

84

85

```typescript { .api }

86

/**

87

* Source location information

88

* Identifies where in source documents messages originated

89

*/

90

interface SourceLocation {

91

/** Document URI where the location exists */

92

document: string;

93

94

/** Position within the document */

95

Position: EnhancedPosition;

96

}

97

98

/**

99

* Range information for multi-character spans

100

* Defines a range within a source document

101

*/

102

interface Range {

103

/** Document URI containing the range */

104

document: string;

105

106

/** Start position of the range */

107

start: Position;

108

109

/** End position of the range */

110

end: Position;

111

}

112

113

/**

114

* Position within a document

115

* Standard line/column position information

116

*/

117

interface Position {

118

/** Line number (0-based) */

119

line: number;

120

121

/** Column number (0-based) */

122

column: number;

123

}

124

125

/**

126

* Enhanced position with additional metadata

127

* Extends Position with source mapping information

128

*/

129

interface EnhancedPosition extends Position {

130

/** Additional position metadata */

131

[key: string]: any;

132

}

133

```

134

135

### Artifact Messages

136

137

Specialized message type for file generation events.

138

139

```typescript { .api }

140

/**

141

* Artifact message for file generation events

142

* Extends Message with artifact-specific details

143

*/

144

interface ArtifactMessage extends Message {

145

/** Artifact details including source map information */

146

Details: Artifact & {

147

/** Optional source map for generated content */

148

sourceMap?: Mappings | RawSourceMap

149

};

150

}

151

```

152

153

**Usage Examples:**

154

155

```typescript

156

import { AutoRest, Channel, Message } from "@microsoft.azure/autorest-core";

157

158

const autorest = new AutoRest();

159

160

// Subscribe to all messages

161

autorest.Message.Subscribe((source, message) => {

162

console.log(`[${message.Channel}] ${message.Text}`);

163

164

// Handle source location information

165

if (message.Source && message.Source.length > 0) {

166

message.Source.forEach(location => {

167

console.log(` at ${location.document}:${location.Position.line}:${location.Position.column}`);

168

});

169

}

170

171

// Handle additional details

172

if (message.Details) {

173

console.log(` Details: ${JSON.stringify(message.Details, null, 2)}`);

174

}

175

});

176

177

// Channel-specific handling

178

autorest.Message.Subscribe((_, message) => {

179

switch (message.Channel) {

180

case Channel.Fatal:

181

case Channel.Error:

182

console.error(`🚨 ERROR: ${message.Text}`);

183

if (message.Source) {

184

message.Source.forEach(loc => {

185

console.error(` at ${loc.document}:${loc.Position.line + 1}:${loc.Position.column + 1}`);

186

});

187

}

188

break;

189

190

case Channel.Warning:

191

console.warn(`⚠️ WARNING: ${message.Text}`);

192

break;

193

194

case Channel.Information:

195

console.info(`ℹ️ INFO: ${message.Text}`);

196

break;

197

198

case Channel.Debug:

199

if (process.env.DEBUG) {

200

console.debug(`πŸ› DEBUG: ${message.Text}`);

201

}

202

break;

203

204

case Channel.Verbose:

205

if (process.env.VERBOSE) {

206

console.log(`πŸ“ VERBOSE: ${message.Text}`);

207

}

208

break;

209

210

case Channel.Hint:

211

console.log(`πŸ’‘ HINT: ${message.Text}`);

212

break;

213

214

case Channel.File:

215

console.log(`πŸ“„ FILE: ${message.Text}`);

216

break;

217

218

case Channel.Configuration:

219

console.log(`βš™οΈ CONFIG: ${message.Text}`);

220

break;

221

}

222

});

223

```

224

225

### Message Filtering and Processing

226

227

```typescript

228

// Collect messages by type

229

const errors: Message[] = [];

230

const warnings: Message[] = [];

231

const infos: Message[] = [];

232

233

autorest.Message.Subscribe((_, message) => {

234

switch (message.Channel) {

235

case Channel.Error:

236

case Channel.Fatal:

237

errors.push(message);

238

break;

239

case Channel.Warning:

240

warnings.push(message);

241

break;

242

case Channel.Information:

243

case Channel.Verbose:

244

infos.push(message);

245

break;

246

}

247

});

248

249

// Process results after completion

250

autorest.Finished.Subscribe((_, result) => {

251

console.log(`\nProcessing completed with ${errors.length} errors, ${warnings.length} warnings`);

252

253

if (errors.length > 0) {

254

console.log("\nErrors:");

255

errors.forEach((error, index) => {

256

console.log(`${index + 1}. ${error.Text}`);

257

if (error.Source) {

258

error.Source.forEach(loc => {

259

console.log(` Location: ${loc.document}:${loc.Position.line + 1}:${loc.Position.column + 1}`);

260

});

261

}

262

});

263

}

264

265

if (warnings.length > 0) {

266

console.log("\nWarnings:");

267

warnings.forEach((warning, index) => {

268

console.log(`${index + 1}. ${warning.Text}`);

269

});

270

}

271

});

272

```

273

274

### Structured Logging

275

276

```typescript

277

// Create structured logger

278

class AutoRestLogger {

279

private errors: Message[] = [];

280

private warnings: Message[] = [];

281

private debug: Message[] = [];

282

283

constructor(autorest: AutoRest) {

284

autorest.Message.Subscribe((_, message) => {

285

this.handleMessage(message);

286

});

287

}

288

289

private handleMessage(message: Message): void {

290

// Store messages

291

switch (message.Channel) {

292

case Channel.Error:

293

case Channel.Fatal:

294

this.errors.push(message);

295

break;

296

case Channel.Warning:

297

this.warnings.push(message);

298

break;

299

case Channel.Debug:

300

this.debug.push(message);

301

break;

302

}

303

304

// Log to appropriate output

305

this.logMessage(message);

306

}

307

308

private logMessage(message: Message): void {

309

const timestamp = new Date().toISOString();

310

const logEntry = {

311

timestamp,

312

channel: message.Channel,

313

text: message.Text,

314

plugin: message.Plugin,

315

key: message.Key ? Array.from(message.Key) : undefined,

316

source: message.Source,

317

details: message.Details

318

};

319

320

// Output as JSON for structured logging

321

console.log(JSON.stringify(logEntry));

322

}

323

324

getErrors(): Message[] { return [...this.errors]; }

325

getWarnings(): Message[] { return [...this.warnings]; }

326

hasErrors(): boolean { return this.errors.length > 0; }

327

hasWarnings(): boolean { return this.warnings.length > 0; }

328

}

329

330

// Usage

331

const autorest = new AutoRest();

332

const logger = new AutoRestLogger(autorest);

333

334

const result = await autorest.Process().finish;

335

336

if (logger.hasErrors()) {

337

console.error("Processing failed with errors:");

338

logger.getErrors().forEach(error => {

339

console.error(`- ${error.Text}`);

340

});

341

process.exit(1);

342

}

343

344

if (logger.hasWarnings()) {

345

console.warn(`Processing completed with ${logger.getWarnings().length} warnings`);

346

}

347

```

348

349

### Message Analysis

350

351

```typescript

352

// Analyze messages for patterns

353

function analyzeMessages(messages: Message[]): void {

354

const byPlugin = new Map<string, Message[]>();

355

const byDocument = new Map<string, Message[]>();

356

357

messages.forEach(msg => {

358

// Group by plugin

359

if (msg.Plugin) {

360

if (!byPlugin.has(msg.Plugin)) {

361

byPlugin.set(msg.Plugin, []);

362

}

363

byPlugin.get(msg.Plugin)!.push(msg);

364

}

365

366

// Group by document

367

if (msg.Source) {

368

msg.Source.forEach(loc => {

369

if (!byDocument.has(loc.document)) {

370

byDocument.set(loc.document, []);

371

}

372

byDocument.get(loc.document)!.push(msg);

373

});

374

}

375

});

376

377

console.log("Messages by plugin:");

378

byPlugin.forEach((msgs, plugin) => {

379

console.log(` ${plugin}: ${msgs.length} messages`);

380

});

381

382

console.log("Messages by document:");

383

byDocument.forEach((msgs, doc) => {

384

console.log(` ${doc}: ${msgs.length} messages`);

385

});

386

}

387

```

388

389

### Custom Message Formatting

390

391

```typescript

392

// Custom message formatter

393

function formatMessage(message: Message): string {

394

let formatted = `[${message.Channel.toUpperCase()}]`;

395

396

if (message.Plugin) {

397

formatted += ` (${message.Plugin})`;

398

}

399

400

formatted += ` ${message.Text}`;

401

402

if (message.Source && message.Source.length > 0) {

403

const locations = message.Source.map(loc =>

404

`${loc.document}:${loc.Position.line + 1}:${loc.Position.column + 1}`

405

).join(', ');

406

formatted += `\n at ${locations}`;

407

}

408

409

if (message.Key) {

410

const keys = Array.from(message.Key).join('.');

411

formatted += `\n key: ${keys}`;

412

}

413

414

return formatted;

415

}

416

417

// Use custom formatter

418

autorest.Message.Subscribe((_, message) => {

419

console.log(formatMessage(message));

420

});

421

```